+Sun Jun 24 12:19:52 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Moved the lib/silccore/silcsockconn.[ch] to the utility
+ library as they clearly belong there. As a plus side we
+ can make the actual socket connection routines platform
+ specific.
+
+ Added also new generic function silc_socket_read and
+ silc_socket_write (that used to be silc_packet_[read/write].
+ The implementation of these are platform specific.
+
Sat Jun 23 16:01:00 EEST 2001 Pekka Riikonen <priikone@silcnet.org>
* Added preliminary support for native WIN32 compilation under
silccommand.c \
silcpacket.c \
silcprotocol.c \
- silcsockconn.c \
silcpayload.c \
silcnotify.c \
silcauth.c \
******************************************************************************/
-/* Writes data from encrypted buffer to the socket connection. If the
- data cannot be written at once, it will be written later with a timeout.
- The data is written from the data section of the buffer, not from head
- or tail section. This automatically pulls the data section towards end
- after writing the data. */
-
-int silc_packet_write(int sock, SilcBuffer src)
-{
- int ret = 0;
-
- SILC_LOG_DEBUG(("Writing data to socket %d", sock));
-
- if (src->len > 0) {
- ret = write(sock, src->data, src->len);
- if (ret < 0) {
- if (errno == EAGAIN) {
- SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
- return -2;
- }
- SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
- return -1;
- }
-
- silc_buffer_pull(src, ret);
- }
-
- SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
-
- return ret;
-}
-
/* Actually sends the packet. This flushes the connections outgoing data
buffer. If data is sent directly to the network this returns the bytes
written, if error occured this returns -1 and if the data could not
SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
/* Write to network */
- ret = silc_packet_write(sock->sock, sock->outbuf);
+ ret = silc_socket_write(sock);
if (ret == -1) {
SILC_LOG_ERROR(("Error sending packet, dropped"));
******************************************************************************/
-/* Reads data from the socket connection into the incoming data buffer.
- However, this does not parse the packet, it only reads some amount from
- the network. If there are more data available that can be read at a time
- the rest of the data will be read later with a timeout and only after
- that the packet is ready to be parsed.
-
- The destination buffer sent as argument must be initialized before
- calling this function, and, the data section and the start of the tail
- section must be same. Ie. we add the read data to the tail section of
- the buffer hence the data section is the start of the buffer.
-
- This returns amount of bytes read or -1 on error or -2 on case where
- all of the data could not be read at once. */
-
-int silc_packet_read(int fd, SilcSocketConnection sock)
-{
- int len = 0;
- unsigned char buf[SILC_PACKET_READ_SIZE];
-
- SILC_LOG_DEBUG(("Reading data from socket %d", fd));
-
- /* Read the data from the socket. */
- len = read(fd, buf, sizeof(buf));
- if (len < 0) {
- if (errno == EAGAIN || errno == EINTR) {
- SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
- return -2;
- }
- SILC_LOG_ERROR(("Cannot read from socket: %d:%s", fd, strerror(errno)));
- return -1;
- }
-
- if (!len)
- return 0;
-
- /* Insert the data to the buffer. */
-
- if (!sock->inbuf)
- sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
-
- /* If the data does not fit to the buffer reallocate it */
- if ((sock->inbuf->end - sock->inbuf->tail) < len)
- sock->inbuf = silc_buffer_realloc(sock->inbuf, sock->inbuf->truelen +
- (len * 2));
- silc_buffer_put_tail(sock->inbuf, buf, len);
- silc_buffer_pull_tail(sock->inbuf, len);
-
- SILC_LOG_DEBUG(("Read %d bytes", len));
-
- return len;
-}
-
/* Processes the received data. This checks the received data and
calls parser callback that handles the actual packet decryption
and parsing. If more than one packet was received this calls the
"Router")));
/* Read some data from connection */
- ret = silc_packet_read(sock->sock, sock);
+ ret = silc_socket_read(sock);
return ret;
}
#ifndef SILCPACKET_H
#define SILCPACKET_H
-/* Amount of bytes to be read from the socket connection at once. */
-#define SILC_PACKET_READ_SIZE 16384
-
/* Default byte size of the packet. */
-#define SILC_PACKET_DEFAULT_SIZE 1024
+#define SILC_PACKET_DEFAULT_SIZE SILC_SOCKET_BUF_SIZE
/* Header length without source and destination ID's. */
#define SILC_PACKET_HEADER_LEN 8 + 2
+++ /dev/null
-/*
-
- silcsockconn.c
-
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
-
- Copyright (C) 1997 - 2000 Pekka Riikonen
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
-*/
-/* $Id$ */
-
-#include "silcincludes.h"
-
-/* Heartbeat context */
-struct SilcSocketConnectionHB {
- uint32 heartbeat;
- SilcSocketConnectionHBCb hb_callback;
- void *hb_context;
- void *timeout_queue;
- SilcTask hb_task;
- SilcSocketConnection sock;
-};
-
-/* Allocates a new socket connection object. The allocated object is
- returned to the new_socket argument. */
-
-void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
- SilcSocketConnection *new_socket)
-{
- SILC_LOG_DEBUG(("Allocating new socket connection object"));
-
- /* Set the pointers. Incoming and outgoing data buffers
- are allocated by the application when they are first used. */
- *new_socket = silc_calloc(1, sizeof(**new_socket));
- (*new_socket)->sock = sock;
- (*new_socket)->type = type;
- (*new_socket)->user_data = user_data;
- (*new_socket)->protocol = NULL;
- (*new_socket)->flags = 0;
- (*new_socket)->inbuf = NULL;
- (*new_socket)->outbuf = NULL;
- (*new_socket)->users++;
-}
-
-/* Free's the Socket connection object. */
-
-void silc_socket_free(SilcSocketConnection sock)
-{
- sock->users--;
- SILC_LOG_DEBUG(("Socket %p refcnt %d->%d", sock, sock->users + 1,
- sock->users));
- if (sock->users < 1) {
- silc_buffer_free(sock->inbuf);
- silc_buffer_free(sock->outbuf);
- if (sock->hb) {
- silc_task_unregister(sock->hb->timeout_queue, sock->hb->hb_task);
- silc_free(sock->hb->hb_context);
- silc_free(sock->hb);
- }
-
- memset(sock, 'F', sizeof(*sock));
- silc_free(sock);
- }
-}
-
-/* Increase the reference counter. */
-
-SilcSocketConnection silc_socket_dup(SilcSocketConnection sock)
-{
- sock->users++;
- SILC_LOG_DEBUG(("Socket %p refcnt %d->%d", sock, sock->users - 1,
- sock->users));
- return sock;
-}
-
-/* Internal timeout callback to perform heartbeat */
-
-SILC_TASK_CALLBACK(silc_socket_heartbeat)
-{
- SilcSocketConnectionHB hb = (SilcSocketConnectionHB)context;
-
- if (!hb->heartbeat)
- return;
-
- if (hb->hb_callback)
- hb->hb_callback(hb->sock, hb->hb_context);
-
- hb->hb_task = silc_task_register(hb->timeout_queue, hb->sock->sock,
- silc_socket_heartbeat,
- context, hb->heartbeat, 0,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_LOW);
-}
-
-/* Sets the heartbeat timeout and prepares the socket for performing
- heartbeat in `heartbeat' intervals (seconds). The `hb_context' is
- allocated by the application and will be sent as argument to the
- `hb_callback' function that is called when the `heartbeat' timeout
- expires. The callback `hb_context' won't be touched by the library
- but will be freed automatically when calling silc_socket_free. The
- `timeout_queue' is the application's scheduler timeout queue. */
-
-void silc_socket_set_heartbeat(SilcSocketConnection sock,
- uint32 heartbeat,
- void *hb_context,
- SilcSocketConnectionHBCb hb_callback,
- void *timeout_queue)
-{
-
- if (sock->hb) {
- silc_task_unregister(sock->hb->timeout_queue, sock->hb->hb_task);
- silc_free(sock->hb->hb_context);
- silc_free(sock->hb);
- }
-
- sock->hb = silc_calloc(1, sizeof(*sock->hb));
- sock->hb->heartbeat = heartbeat;
- sock->hb->hb_context = hb_context;
- sock->hb->hb_callback = hb_callback;
- sock->hb->timeout_queue = timeout_queue;
- sock->hb->sock = sock;
- sock->hb->hb_task = silc_task_register(timeout_queue, sock->sock,
- silc_socket_heartbeat,
- (void *)sock->hb, heartbeat, 0,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_LOW);
-}
+++ /dev/null
-/****h* silccore/silcsockconn.h
- *
- * NAME
- *
- * silcsockconn.h
- *
- * COPYRIGHT
- *
- * Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
- *
- * Copyright (C) 1997 - 2000 Pekka Riikonen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * DESCRIPTION
- *
- * Implementation of the Socket Connection object. The SilcSocketConnection
- * is used by all applications to represent a socket based connection
- * to the network. The Socket Connection object handles inbound and outbound
- * data buffers, can perform keepalive actions for the connection and
- * supports connection based protocols as well.
- *
- ***/
-
-#ifndef SILCSOCKCONN_H
-#define SILCSOCKCONN_H
-
-/****s* silccore/SilcSocketConnectionAPI/SilcSocketConnection
- *
- * NAME
- *
- * typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
- *
- * DESCRIPTION
- *
- * This context is forward declaration for the SilcSocketConnectionStruct.
- * This is allocated by the silc_socket_alloc and freed by the
- * silc_socket_free function. The silc_socket_dup can be used to
- * increase the reference counter of the context. The data is freed
- * by the silc_socket_free function only after the reference counter
- * hits zero.
- *
- ***/
-typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
-
-/****s* silccore/SilcSocketConnectionAPI/SilcSocketConnectionHB
- *
- * NAME
- *
- * typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
- *
- * DESCRIPTION
- *
- * This context is the heartbeat context for the SilcSockeConnection.
- * It is meant to hold the keepalive information for the connection.
- * This is allocated internally and freed internally by the
- * interface routines.
- *
- ***/
-typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
-
-/****d* silccore/SilcSocketConnectionAPI/SilcSocketType
- *
- * NAME
- *
- * typedef enum { ... } SilcSocketType;
- *
- * DESCRIPTION
- *
- * Socket types. These identifies the socket connection. There
- * are four different types; unknown, client, server and router.
- * Unknown connections are connections that hasn't advanced long
- * enough so that we might know which type of connection it is.
- * It is the applications responsibility to update the type
- * information when it becomes available.
- *
- * SOURCE
- */
-typedef enum {
- SILC_SOCKET_TYPE_UNKNOWN = 0,
- SILC_SOCKET_TYPE_CLIENT = 1,
- SILC_SOCKET_TYPE_SERVER = 2,
- SILC_SOCKET_TYPE_ROUTER = 3
-} SilcSocketType;
-/***/
-
-/* Socket flags */
-#define SILC_SF_NONE 0
-#define SILC_SF_INBUF_PENDING 1
-#define SILC_SF_OUTBUF_PENDING 2
-#define SILC_SF_DISCONNECTING 3
-#define SILC_SF_DISCONNECTED 4
-
-/****f* silccore/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
- *
- * SYNOPSIS
- *
- * typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
- * void *context);
- *
- * DESCRIPTION
- *
- * Heartbeat callback function. This is the function in the application
- * that this library will call when it is time to send the keepalive
- * packet SILC_PACKET_HEARTBEAT.
- *
- ***/
-typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
- void *context);
-
-/****s* silccore/SilcSocketConnectionAPI/SilcSocketConnectionStruct
- *
- * NAME
- *
- * struct SilcSocketConnectionStruct { ... };
- *
- * DESCRIPTION
- *
- * This object holds information about the connected sockets to the server.
- * This is quite important object since this is referenced by the server all
- * the time when figuring out what the connection is supposed to be doing
- * and to whom we should send a message. This structure is the structure
- * for the SilcSocketConnection forward declaration.
- *
- * Following short description of the fields:
- *
- * int sock
- *
- * The actual connected socket. This is usually saved when accepting
- * new connection to the server.
- *
- * SilcSocketType type
- *
- * Type of the socket. This identifies the type of the connection. This
- * is mainly used to identify whether the connection is a client or a
- * server connection.
- *
- * void *user_data
- *
- * This is a pointer to a data that is is saved here at the same
- * time a new connection object is allocated. Usually this is a
- * back-pointer to some important data for fast referencing. For
- * SILC server this is a pointer to the ID list and for SILC client
- * to object holding active connections (windows).
- *
- * SilcProtocol protocol
- *
- * Protocol object for the socket. Currently only one protocol can be
- * executing at a time for a particular socket.
- *
- * uint32 flags
- *
- * Socket flags that indicate the status of the socket. This can
- * indicate several different status that can affect the use of the
- * socket object.
- *
- * int users
- *
- * Reference counter. When allocated it is set to one (1) and it won't
- * be freed until it hits zero (0).
- *
- * char *hostname
- * char *ip
- * uint16 port
- *
- * Resolved hostname, IP address and port of the connection who owns
- * this object.
- *
- * SilcBuffer inbuf
- * SilcBuffer outbuf
- *
- * Incoming and outgoing buffers for the particular socket connection.
- * Incoming data from the socket is put after decryption in to the
- * inbuf buffer and outgoing data after encryption is put to the outbuf
- * buffer.
- *
- * SilcSocketConnectionHB hb
- *
- * The heartbeat context. If NULL, heartbeat is not performed.
- *
- ***/
-struct SilcSocketConnectionStruct {
- int sock;
- SilcSocketType type;
- void *user_data;
- SilcProtocol protocol;
- uint32 flags;
- int users;
-
- char *hostname;
- char *ip;
- uint16 port;
-
- SilcBuffer inbuf;
- SilcBuffer outbuf;
-
- SilcSocketConnectionHB hb;
-};
-
-/* Macros */
-
-/* Generic manipulation of flags */
-#define SF_SET(x, f) (x)->flags |= (1L << (f))
-#define SF_UNSET(x, f) (x)->flags &= ~(1L << (f))
-#define SF_IS(x, f) ((x)->flags & (1L << (f)))
-
-/* Setting/Unsetting flags */
-#define SILC_SET_OUTBUF_PENDING(x) SF_SET((x), SILC_SF_OUTBUF_PENDING)
-#define SILC_SET_INBUF_PENDING(x) SF_SET((x), SILC_SF_INBUF_PENDING)
-#define SILC_SET_DISCONNECTING(x) SF_SET((x), SILC_SF_DISCONNECTING)
-#define SILC_SET_DISCONNECTED(x) SF_SET((x), SILC_SF_DISCONNECTED)
-#define SILC_UNSET_OUTBUF_PENDING(x) SF_UNSET((x), SILC_SF_OUTBUF_PENDING)
-#define SILC_UNSET_INBUF_PENDING(x) SF_UNSET((x), SILC_SF_INBUF_PENDING)
-#define SILC_UNSET_DISCONNECTING(x) SF_UNSET((x), SILC_SF_DISCONNECTING)
-#define SILC_UNSET_DISCONNECTED(x) SF_UNSET((x), SILC_SF_DISCONNECTED)
-
-/* Checking for flags */
-#define SILC_IS_OUTBUF_PENDING(x) SF_IS((x), SILC_SF_OUTBUF_PENDING)
-#define SILC_IS_INBUF_PENDING(x) SF_IS((x), SILC_SF_INBUF_PENDING)
-#define SILC_IS_DISCONNECTING(x) SF_IS((x), SILC_SF_DISCONNECTING)
-#define SILC_IS_DISCONNECTED(x) SF_IS((x), SILC_SF_DISCONNECTED)
-
-/* Prototypes */
-
-/****f* silccore/SilcSocketConnectionAPI/silc_socket_alloc
- *
- * SYNOPSIS
- *
- * void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
- * SilcSocketConnection *new_socket);
- *
- * DESCRIPTION
- *
- * Allocates a new socket connection object. The allocated object is
- * returned to the new_socket argument. The `sock' is the socket
- * for the connection, the `type' the initial type of the connection and
- * the `user_data' a application specific pointer.
- *
- ***/
-void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
- SilcSocketConnection *new_socket);
-
-/****f* silccore/SilcSocketConnectionAPI/silc_socket_free
- *
- * SYNOPSIS
- *
- * void silc_socket_free(SilcSocketConnection sock);
- *
- * DESCRIPTION
- *
- * Frees the socket connection context. This frees it only if the
- * reference counter of the socket is zero, otherwise it decreases the
- * reference counter.
- *
- ***/
-void silc_socket_free(SilcSocketConnection sock);
-
-/****f* silccore/SilcSocketConnectionAPI/silc_socket_dup
- *
- * SYNOPSIS
- *
- * SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
- *
- * DESCRIPTION
- *
- * Duplicates the socket context. This actually does not duplicate
- * any data, instead this increases the reference counter of the
- * context. The reference counter is decreased by calling the
- * silc_socket_free function and it frees the data when the counter
- * hits zero.
- *
- ***/
-SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
-
-/****f* silccore/SilcSocketConnectionAPI/silc_socket_set_heartbeat
- *
- * SYNOPSIS
- *
- * void silc_socket_set_heartbeat(SilcSocketConnection sock,
- * uint32 heartbeat,
- * void *hb_context,
- * SilcSocketConnectionHBCb hb_callback,
- * void *timeout_queue);
- *
- * DESCRIPTION
- *
- * Sets the heartbeat timeout and prepares the socket for performing
- * heartbeat in `heartbeat' intervals (seconds). The `hb_context' is
- * allocated by the application and will be sent as argument to the
- * `hb_callback' function that is called when the `heartbeat' timeout
- * expires. The callback `hb_context' won't be touched by the library
- * but will be freed automatically when calling silc_socket_free. The
- * `timeout_queue' is the application's scheduler timeout queue.
- *
- ***/
-void silc_socket_set_heartbeat(SilcSocketConnection sock,
- uint32 heartbeat,
- void *hb_context,
- SilcSocketConnectionHBCb hb_callback,
- void *timeout_queue);
-
-#endif
silctask.c \
silcschedule.c \
silcutil.c \
- silchashtable.c
+ silchashtable.c \
+ silcsockconn.c
EXTRA_DIST = *.h
silcsockconn.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2000 Pekka Riikonen
+ Copyright (C) 1997 - 2001 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
* Reads data from the socket connection into the incoming data buffer.
* It reads as much as possible from the socket connection. This returns
* amount of bytes read or -1 on error or -2 on case where all of the
- * data could not be read at once. Implementation of this funtion
+ * data could not be read at once. Implementation of this function
* may be platform specific.
*
***/
* data cannot be written at once, it must be written at later time.
* The data is written from the data section of the buffer, not from head
* or tail section. This automatically pulls the data section towards end
- * after writing the data. Implementation of this functions may be
+ * after writing the data. Implementation of this function may be
* platform specific.
*
***/
libsilcunixutil_a_SOURCES = \
silcunixschedule.c \
silcunixnet.c \
- silcunixutil.c
+ silcunixutil.c \
+ silcunixsockconn.c
EXTRA_DIST = *.h
int silc_socket_read(SilcSocketConnection sock)
{
int len = 0;
- unsigned char buf[SILC_PACKET_READ_SIZE];
+ unsigned char buf[SILC_SOCKET_READ_SIZE];
int fd = sock->sock;
SILC_LOG_DEBUG(("Reading data from socket %d", fd));
/* Insert the data to the buffer. */
if (!sock->inbuf)
- sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
+ sock->inbuf = silc_buffer_alloc(SILC_SOCKET_BUF_SIZE);
/* If the data does not fit to the buffer reallocate it */
if ((sock->inbuf->end - sock->inbuf->tail) < len)
silcunixutil.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@sillcnet.org>
- Copyright (C) 1997 - 2000 Pekka Riikonen
+ Copyright (C) 1997 - 2001 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
connection returns directly. To get the result of the connect() one
must select() the socket and read the result after it's ready. */
-/* XXX Is the socket on WIN32 always non-blocking? */
-
int silc_net_create_connection_async(int port, char *host)
{
SOCKET sock;
some more tweaking I can abandon this silc_select() thingy all together
and move the generic code to unix/ and program the SILC Scheduler
interface all together as platform specific. It is here just to
- use as match common code as possible... -Pekka */
+ use as much common code as possible... -Pekka */
/* Our "select()" for WIN32. This actually is not the select() and does
not call Winsock's select() (since it cannot be used for our purposes)