Merged silc_1_0_branch to trunk.
[silc.git] / lib / silcutil / silcsockconn.h
1 /*
2
3   silcsockconn.h
4
5   Author: Pekka Riikonen <priikone@silnet.org>
6
7   Copyright (C) 1997 - 2001, 2003 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 /****h* silcutil/SILC Socket Interface
21  *
22  * DESCRIPTION
23  *
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.
29  *
30  ***/
31
32 #ifndef SILCSOCKCONN_H
33 #define SILCSOCKCONN_H
34
35 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnection
36  *
37  * NAME
38  *
39  *    typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
40  *
41  * DESCRIPTION
42  *
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
48  *    hits zero.
49  *
50  ***/
51 typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
52
53 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHB
54  *
55  * NAME
56  *
57  *    typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
58  *
59  * DESCRIPTION
60  *
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
64  *    interface routines.
65  *
66  ***/
67 typedef struct SilcSocketConnectionHBStruct *SilcSocketConnectionHB;
68
69 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionQos
70  *
71  * NAME
72  *
73  *    typedef struct SilcSocketConnectionQosStruct *SilcSocketConnectionQos;
74  *
75  * DESCRIPTION
76  *
77  *    This structure is "Quality of Service" structure for the socket
78  *    connection and is set with silc_socket_set_qos function for a
79  *    socket context.
80  *
81  ***/
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;
91   SilcUInt32 data_len;
92   SilcSocketConnection sock;
93 } *SilcSocketConnectionQos;
94
95 /****d* silcutil/SilcSocketConnectionAPI/SilcSocketType
96  *
97  * NAME
98  *
99  *    typedef enum { ... } SilcSocketType;
100  *
101  * DESCRIPTION
102  *
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.
109  *
110  * SOURCE
111  */
112 typedef enum {
113   SILC_SOCKET_TYPE_UNKNOWN = 0,
114   SILC_SOCKET_TYPE_CLIENT = 1,
115   SILC_SOCKET_TYPE_SERVER = 2,
116   SILC_SOCKET_TYPE_ROUTER = 3
117 } SilcSocketType;
118 /***/
119
120 /* Socket flags */
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
130
131 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
132  *
133  * NAME
134  *
135  *    struct SilcSocketConnectionStruct { ... };
136  *
137  * DESCRIPTION
138  *
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.
144  *
145  *    Following short description of the fields:
146  *
147  *    int sock
148  *
149  *      The actual connected socket. This is usually saved when accepting
150  *      new connection to the server.
151  *
152  *    SilcSocketType type
153  *
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
156  *      server connection.
157  *
158  *    void *user_data
159  *
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).
165  *
166  *    SilcProtocol protocol
167  *
168  *      Protocol object for the socket. Currently only one protocol can be
169  *      executing at a time for a particular socket.
170  *
171  *    SilcUInt32 flags
172  *
173  *      Socket flags that indicate the status of the socket. This can
174  *      indicate several different status that can affect the use of the
175  *      socket object.
176  *
177  *    int users
178  *
179  *      Reference counter. When allocated it is set to one (1) and it won't
180  *      be freed until it hits zero (0).
181  *
182  *    SilcSocketConnectionHB hb
183  *
184  *      The heartbeat context.  If NULL, heartbeat is not performed.
185  *
186  *    SilcBuffer inbuf
187  *    SilcBuffer outbuf
188  *
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
192  *      buffer.
193  *
194  *    char *hostname
195  *    char *ip
196  *    SilcUInt16 port
197  *
198  *      Resolved hostname, IP address and port of the connection who owns
199  *      this object.
200  *
201  ***/
202 struct SilcSocketConnectionStruct {
203   int sock;
204   SilcSocketType type;
205   void *user_data;
206   SilcProtocol protocol;
207   SilcUInt32 flags;
208   int users;
209
210   SilcSocketConnectionHB hb;
211   SilcSocketConnectionQos qos;
212
213   SilcBuffer inbuf;
214   SilcBuffer outbuf;
215
216   char *hostname;
217   char *ip;
218   SilcUInt16 port;
219   SilcUInt8 sock_error;
220   SilcUInt8 version;
221 };
222
223 /* Macros */
224
225 /* Check for specific protocol version */
226 #define SILC_PROTOCOL_VERSION(s, maj, min) (s->version == maj##min)
227
228 /* Amount of bytes to be read from the socket connection at once. */
229 #define SILC_SOCKET_READ_SIZE 16384
230
231 /* Default socket buffer size. */
232 #define SILC_SOCKET_BUF_SIZE 1024
233
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)))
238
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)
254
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)
263
264 /* Prototypes */
265
266 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_alloc
267  *
268  * SYNOPSIS
269  *
270  *    void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
271  *                           SilcSocketConnection *new_socket);
272  *
273  * DESCRIPTION
274  *
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.
279  *
280  ***/
281 void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
282                        SilcSocketConnection *new_socket);
283
284 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_free
285  *
286  * SYNOPSIS
287  *
288  *    void silc_socket_free(SilcSocketConnection sock);
289  *
290  * DESCRIPTION
291  *
292  *    Frees the socket connection context. This frees it only if the
293  *    reference counter of the socket is zero, otherwise it decreases the
294  *    reference counter.
295  *
296  ***/
297 void silc_socket_free(SilcSocketConnection sock);
298
299 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_dup
300  *
301  * SYNOPSIS
302  *
303  *    SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
304  *
305  * DESCRIPTION
306  *
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
311  *    hits zero.
312  *
313  ***/
314 SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
315
316 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_read
317  *
318  * SYNOPSIS
319  *
320  *    int silc_socket_read(SilcSocketConnection sock);
321  *
322  * DESCRIPTION
323  *
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.
329  *
330  ***/
331 int silc_socket_read(SilcSocketConnection sock);
332
333 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_write
334  *
335  * SYNOPSIS
336  *
337  *    int silc_socket_write(SilcSocketConnection sock);
338  *
339  * DESCRIPTION
340  *
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
346  *    platform specific.
347  *
348  ***/
349 int silc_socket_write(SilcSocketConnection sock);
350
351 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_get_error
352  *
353  * SYNOPSIS
354  *
355  *    bool silc_socket_get_error(SilcSocketConnection sock, char *error,
356  *                               SilcUInt32 error_len);
357  *
358  * DESCRIPTION
359  *
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.
363  *
364  ***/
365 bool silc_socket_get_error(SilcSocketConnection sock, char *error,
366                            SilcUInt32 error_len);
367
368 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
369  *
370  * SYNOPSIS
371  *
372  *    typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
373  *                                             void *context);
374  *
375  * DESCRIPTION
376  *
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.
380  *
381  ***/
382 typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
383                                          void *context);
384
385 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_heartbeat
386  *
387  * SYNOPSIS
388  *
389  *    void silc_socket_set_heartbeat(SilcSocketConnection sock,
390  *                                   SilcUInt32 heartbeat,
391  *                                   void *hb_context,
392  *                                   SilcSocketConnectionHBCb hb_callback,
393  *                                   SilcSchedule schedule);
394  *
395  * DESCRIPTION
396  *
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.
404  *
405  ***/
406 void silc_socket_set_heartbeat(SilcSocketConnection sock,
407                                SilcUInt32 heartbeat,
408                                void *hb_context,
409                                SilcSocketConnectionHBCb hb_callback,
410                                SilcSchedule schedule);
411
412 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_qos
413  *
414  * SYNOPSIS
415  *
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)
422  *
423  * DESCRIPTION
424  *
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.
437  *
438  ***/
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);
445
446 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketHostLookupCb
447  *
448  * SYNOPSIS
449  *
450  *    typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
451  *                                           void *context);
452  *
453  * DESCRIPTION
454  *
455  *    Asynchronous host lookup callback function that will be called
456  *    when the lookup is performed.
457  *
458  ***/
459 typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
460                                        void *context);
461
462 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_host_lookup
463  *
464  * SYNOPSIS
465  *
466  *    void silc_socket_host_lookup(SilcSocketConnection sock,
467  *                                 bool port_lookup,
468  *                                 SilcSocketHostLookupCb callback,
469  *                                 void *context,
470  *                                 SilcSchedule schedule);
471  *
472  * DESCRIPTION
473  *
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
482  *    called.
483  *
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.
490  *
491  ***/
492 void silc_socket_host_lookup(SilcSocketConnection sock,
493                              bool port_lookup,
494                              SilcSocketHostLookupCb callback,
495                              void *context,
496                              SilcSchedule schedule);
497
498 #endif