5 Author: Pekka Riikonen <priikone@silnet.org>
7 Copyright (C) 1997 - 2001, 2003 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 /****h* silcutil/SILC Socket Interface
24 * Implementation of the Socket Connection object. The SilcSocketConnection
25 * is used by all applications to represent a socket based connection
26 * to the network. The Socket Connection object handles inbound and outbound
27 * data buffers, can perform keepalive actions for the connection and
28 * supports connection based protocols as well.
32 #ifndef SILCSOCKCONN_H
33 #define SILCSOCKCONN_H
35 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnection
39 * typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
43 * This context is forward declaration for the SilcSocketConnectionStruct.
44 * This is allocated by the silc_socket_alloc and freed by the
45 * silc_socket_free function. The silc_socket_dup can be used to
46 * increase the reference counter of the context. The data is freed
47 * by the silc_socket_free function only after the reference counter
51 typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
53 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHB
57 * typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
61 * This context is the heartbeat context for the SilcSockeConnection.
62 * It is meant to hold the keepalive information for the connection.
63 * This is allocated internally and freed internally by the
67 typedef struct SilcSocketConnectionHBStruct *SilcSocketConnectionHB;
69 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionQos
73 * typedef struct SilcSocketConnectionQosStruct *SilcSocketConnectionQos;
77 * This structure is "Quality of Service" structure for the socket
78 * connection and is set with silc_socket_set_qos function for a
82 typedef struct SilcSocketConnectionQosStruct {
83 SilcUInt16 read_limit_bytes; /* Max read bytes */
84 SilcUInt16 read_rate; /* Max read rate/second */
85 SilcUInt16 limit_sec; /* Limit seconds */
86 SilcUInt32 limit_usec; /* Limit microseconds */
87 SilcSchedule schedule;
88 struct timeval next_limit;
89 unsigned int cur_rate : 31;
90 unsigned int applied : 1;
92 SilcSocketConnection sock;
93 } *SilcSocketConnectionQos;
95 /****d* silcutil/SilcSocketConnectionAPI/SilcSocketType
99 * typedef enum { ... } SilcSocketType;
103 * Socket types. These identifies the socket connection. There
104 * are four different types; unknown, client, server and router.
105 * Unknown connections are connections that hasn't advanced long
106 * enough so that we might know which type of connection it is.
107 * It is the applications responsibility to update the type
108 * information when it becomes available.
113 SILC_SOCKET_TYPE_UNKNOWN = 0,
114 SILC_SOCKET_TYPE_CLIENT = 1,
115 SILC_SOCKET_TYPE_SERVER = 2,
116 SILC_SOCKET_TYPE_ROUTER = 3
121 #define SILC_SF_NONE 0
122 #define SILC_SF_INBUF_PENDING 1 /* data in inbound buffer */
123 #define SILC_SF_OUTBUF_PENDING 2 /* data in outbound buffer */
124 #define SILC_SF_DISCONNECTING 3 /* socket disconnecting */
125 #define SILC_SF_DISCONNECTED 4 /* socket disconnected */
126 #define SILC_SF_HOST_LOOKUP 5 /* performing host lookup for socket */
127 #define SILC_SF_DISABLED 6 /* socket connection is disabled,
128 no data is sent or received. */
129 #define SILC_SF_LISTENER 7
131 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
135 * struct SilcSocketConnectionStruct { ... };
139 * This object holds information about the connected sockets to the server.
140 * This is quite important object since this is referenced by the server all
141 * the time when figuring out what the connection is supposed to be doing
142 * and to whom we should send a message. This structure is the structure
143 * for the SilcSocketConnection forward declaration.
145 * Following short description of the fields:
149 * The actual connected socket. This is usually saved when accepting
150 * new connection to the server.
152 * SilcSocketType type
154 * Type of the socket. This identifies the type of the connection. This
155 * is mainly used to identify whether the connection is a client or a
160 * This is a pointer to a data that is is saved here at the same
161 * time a new connection object is allocated. Usually this is a
162 * back-pointer to some important data for fast referencing. For
163 * SILC server this is a pointer to the ID list and for SILC client
164 * to object holding active connections (windows).
166 * SilcProtocol protocol
168 * Protocol object for the socket. Currently only one protocol can be
169 * executing at a time for a particular socket.
173 * Socket flags that indicate the status of the socket. This can
174 * indicate several different status that can affect the use of the
179 * Reference counter. When allocated it is set to one (1) and it won't
180 * be freed until it hits zero (0).
182 * SilcSocketConnectionHB hb
184 * The heartbeat context. If NULL, heartbeat is not performed.
189 * Incoming and outgoing buffers for the particular socket connection.
190 * Incoming data from the socket is put after decryption in to the
191 * inbuf buffer and outgoing data after encryption is put to the outbuf
198 * Resolved hostname, IP address and port of the connection who owns
202 struct SilcSocketConnectionStruct {
206 SilcProtocol protocol;
210 SilcSocketConnectionHB hb;
211 SilcSocketConnectionQos qos;
219 SilcUInt8 sock_error;
225 /* Check for specific protocol version */
226 #define SILC_PROTOCOL_VERSION(s, maj, min) (s->version == maj##min)
228 /* Amount of bytes to be read from the socket connection at once. */
229 #define SILC_SOCKET_READ_SIZE 16384
231 /* Default socket buffer size. */
232 #define SILC_SOCKET_BUF_SIZE 1024
234 /* Generic manipulation of flags */
235 #define SF_SET(x, f) (x)->flags |= (1L << (f))
236 #define SF_UNSET(x, f) (x)->flags &= ~(1L << (f))
237 #define SF_IS(x, f) ((x)->flags & (1L << (f)))
239 /* Setting/Unsetting flags */
240 #define SILC_SET_OUTBUF_PENDING(x) SF_SET((x), SILC_SF_OUTBUF_PENDING)
241 #define SILC_SET_INBUF_PENDING(x) SF_SET((x), SILC_SF_INBUF_PENDING)
242 #define SILC_SET_DISCONNECTING(x) SF_SET((x), SILC_SF_DISCONNECTING)
243 #define SILC_SET_DISCONNECTED(x) SF_SET((x), SILC_SF_DISCONNECTED)
244 #define SILC_SET_HOST_LOOKUP(x) SF_SET((x), SILC_SF_HOST_LOOKUP)
245 #define SILC_SET_DISABLED(x) SF_SET((x), SILC_SF_DISABLED)
246 #define SILC_SET_LISTENER(x) SF_SET((x), SILC_SF_LISTENER)
247 #define SILC_UNSET_OUTBUF_PENDING(x) SF_UNSET((x), SILC_SF_OUTBUF_PENDING)
248 #define SILC_UNSET_INBUF_PENDING(x) SF_UNSET((x), SILC_SF_INBUF_PENDING)
249 #define SILC_UNSET_DISCONNECTING(x) SF_UNSET((x), SILC_SF_DISCONNECTING)
250 #define SILC_UNSET_DISCONNECTED(x) SF_UNSET((x), SILC_SF_DISCONNECTED)
251 #define SILC_UNSET_HOST_LOOKUP(x) SF_UNSET((x), SILC_SF_HOST_LOOKUP)
252 #define SILC_UNSET_DISABLED(x) SF_UNSET((x), SILC_SF_DISABLED)
253 #define SILC_UNSET_LISTENER(x) SF_UNSET((x), SILC_SF_LISTENER)
255 /* Checking for flags */
256 #define SILC_IS_OUTBUF_PENDING(x) SF_IS((x), SILC_SF_OUTBUF_PENDING)
257 #define SILC_IS_INBUF_PENDING(x) SF_IS((x), SILC_SF_INBUF_PENDING)
258 #define SILC_IS_DISCONNECTING(x) SF_IS((x), SILC_SF_DISCONNECTING)
259 #define SILC_IS_DISCONNECTED(x) SF_IS((x), SILC_SF_DISCONNECTED)
260 #define SILC_IS_HOST_LOOKUP(x) SF_IS((x), SILC_SF_HOST_LOOKUP)
261 #define SILC_IS_DISABLED(x) SF_IS((x), SILC_SF_DISABLED)
262 #define SILC_IS_LISTENER(x) SF_IS((x), SILC_SF_LISTENER)
266 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_alloc
270 * void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
271 * SilcSocketConnection *new_socket);
275 * Allocates a new socket connection object. The allocated object is
276 * returned to the new_socket argument. The `sock' is the socket
277 * for the connection, the `type' the initial type of the connection and
278 * the `user_data' a application specific pointer.
281 void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
282 SilcSocketConnection *new_socket);
284 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_free
288 * void silc_socket_free(SilcSocketConnection sock);
292 * Frees the socket connection context. This frees it only if the
293 * reference counter of the socket is zero, otherwise it decreases the
297 void silc_socket_free(SilcSocketConnection sock);
299 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_dup
303 * SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
307 * Duplicates the socket context. This actually does not duplicate
308 * any data, instead this increases the reference counter of the
309 * context. The reference counter is decreased by calling the
310 * silc_socket_free function and it frees the data when the counter
314 SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
316 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_read
320 * int silc_socket_read(SilcSocketConnection sock);
324 * Reads data from the socket connection into the incoming data buffer.
325 * It reads as much as possible from the socket connection. This returns
326 * amount of bytes read or -1 on error or -2 on case where all of the
327 * data could not be read at once. Implementation of this function
328 * may be platform specific.
331 int silc_socket_read(SilcSocketConnection sock);
333 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_write
337 * int silc_socket_write(SilcSocketConnection sock);
341 * Writes data from the outgoing buffer to the socket connection. If the
342 * data cannot be written at once, it must be written at later time.
343 * The data is written from the data section of the buffer, not from head
344 * or tail section. This automatically pulls the data section towards end
345 * after writing the data. Implementation of this function may be
349 int silc_socket_write(SilcSocketConnection sock);
351 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_get_error
355 * bool silc_socket_get_error(SilcSocketConnection sock, char *error,
356 * SilcUInt32 error_len);
360 * Returns human readable error message into the `error' buffer if
361 * the socket is in error status. Returns TRUE if error message was
362 * written into the buffer and FALSE if there is not socket error.
365 bool silc_socket_get_error(SilcSocketConnection sock, char *error,
366 SilcUInt32 error_len);
368 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
372 * typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
377 * Heartbeat callback function. This is the function in the application
378 * that this library will call when it is time to send the keepalive
379 * packet SILC_PACKET_HEARTBEAT.
382 typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
385 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_heartbeat
389 * void silc_socket_set_heartbeat(SilcSocketConnection sock,
390 * SilcUInt32 heartbeat,
392 * SilcSocketConnectionHBCb hb_callback,
393 * SilcSchedule schedule);
397 * Sets the heartbeat timeout and prepares the socket for performing
398 * heartbeat in `heartbeat' intervals (seconds). The `hb_context' is
399 * allocated by the application and will be sent as argument to the
400 * `hb_callback' function that is called when the `heartbeat' timeout
401 * expires. The callback `hb_context' won't be touched by the library
402 * but and must be freed by the application. The `schedule' is the
403 * application's scheduler.
406 void silc_socket_set_heartbeat(SilcSocketConnection sock,
407 SilcUInt32 heartbeat,
409 SilcSocketConnectionHBCb hb_callback,
410 SilcSchedule schedule);
412 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_qos
416 * void silc_socket_set_qos(SilcSocketConnection sock,
417 * SilcUInt32 read_rate,
418 * SilcUInt32 read_limit_bytes,
419 * SilcUInt32 limit_sec,
420 * SilcUInt32 limit_usec,
421 * SilcSchedule schedule)
425 * Sets a "Quality of Service" settings for socket connection `sock'.
426 * The `read_rate' specifies the maximum read operations per second.
427 * If more read operations are executed the limit will be applied for
428 * the reading. The `read_limit_bytes' specifies the maximum data
429 * that is read. It is guaranteed that silc_socket_read never returns
430 * more that `read_limit_bytes' of data. If more is read the limit
431 * will be applied for the reading. The `limit_sec' and `limit_usec'
432 * specifies the limit that is applied if `read_rate' and/or
433 * `read_limit_bytes' is reached. The `schedule' is the application's
434 * scheduler. If all arguments except `sock' are NULL or zero this
435 * resets the QoS from the socket, all QoS for this socket that may
436 * be pending will be cancelled.
439 void silc_socket_set_qos(SilcSocketConnection sock,
440 SilcUInt32 read_rate,
441 SilcUInt32 read_limit_bytes,
442 SilcUInt32 limit_sec,
443 SilcUInt32 limit_usec,
444 SilcSchedule schedule);
446 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketHostLookupCb
450 * typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
455 * Asynchronous host lookup callback function that will be called
456 * when the lookup is performed.
459 typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
462 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_host_lookup
466 * void silc_socket_host_lookup(SilcSocketConnection sock,
468 * SilcSocketHostLookupCb callback,
470 * SilcSchedule schedule);
474 * Performs asynchronous host name and IP address lookups for the
475 * specified socket connection. This may be called when the socket
476 * connection is created and the full IP address and fully qualified
477 * domain name information is desired. The `callback' with `context'
478 * will be called after the lookup is performed. The `schedule'
479 * is the application's scheduler which the lookup routine needs.
480 * If the socket connection is freed during the lookup the library
481 * will automatically cancel the lookup and the `callback' will not be
484 * If `port_lookup' is TRUE then the remote port of the socket
485 * connection is resolved. After the information is resolved they
486 * are accessible using sock->ip and sock->hostname pointers. Note
487 * that if the both IP and FQDN could not be resolved the sock->hostname
488 * includes the IP address of the remote host. The resolved port is
489 * available in sock->port.
492 void silc_socket_host_lookup(SilcSocketConnection sock,
494 SilcSocketHostLookupCb callback,
496 SilcSchedule schedule);