Heartbeat context is not freed automatically by the library
[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 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; either version 2 of the License, or
12   (at your option) any later version.
13  
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 /****h* silcutil/SILC Socket Interface
22  *
23  * DESCRIPTION
24  *
25  * Implementation of the Socket Connection object. The SilcSocketConnection
26  * is used by all applications to represent a socket based connection
27  * to the network. The Socket Connection object handles inbound and outbound
28  * data buffers, can perform keepalive actions for the connection and
29  * supports connection based protocols as well.
30  *
31  ***/
32
33 #ifndef SILCSOCKCONN_H
34 #define SILCSOCKCONN_H
35
36 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnection
37  *
38  * NAME
39  * 
40  *    typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
41  *
42  * DESCRIPTION
43  *
44  *    This context is forward declaration for the SilcSocketConnectionStruct.
45  *    This is allocated by the silc_socket_alloc and freed by the
46  *    silc_socket_free function. The silc_socket_dup can be used to
47  *    increase the reference counter of the context. The data is freed
48  *    by the silc_socket_free function only after the reference counter
49  *    hits zero.
50  *
51  ***/
52 typedef struct SilcSocketConnectionStruct *SilcSocketConnection;
53
54 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHB
55  *
56  * NAME
57  * 
58  *    typedef struct SilcSocketConnectionHB *SilcSocketConnectionHB;
59  *
60  * DESCRIPTION
61  *
62  *    This context is the heartbeat context for the SilcSockeConnection.
63  *    It is meant to hold the keepalive information for the connection.
64  *    This is allocated internally and freed internally by the 
65  *    interface routines.
66  *
67  ***/
68 typedef struct SilcSocketConnectionHBStruct *SilcSocketConnectionHB;
69
70 /****d* silcutil/SilcSocketConnectionAPI/SilcSocketType
71  *
72  * NAME
73  * 
74  *    typedef enum { ... } SilcSocketType;
75  *
76  * DESCRIPTION
77  *
78  *    Socket types. These identifies the socket connection. There
79  *    are four different types; unknown, client, server and router.
80  *    Unknown connections are connections that hasn't advanced long
81  *    enough so that we might know which type of connection it is.
82  *    It is the applications responsibility to update the type 
83  *    information when it becomes available.
84  *
85  * SOURCE
86  */
87 typedef enum {
88   SILC_SOCKET_TYPE_UNKNOWN = 0,
89   SILC_SOCKET_TYPE_CLIENT = 1,
90   SILC_SOCKET_TYPE_SERVER = 2,
91   SILC_SOCKET_TYPE_ROUTER = 3
92 } SilcSocketType;
93 /***/
94
95 /* Socket flags */
96 #define SILC_SF_NONE             0
97 #define SILC_SF_INBUF_PENDING    1 /* data in inbound buffer */
98 #define SILC_SF_OUTBUF_PENDING   2 /* data in outbound buffer */
99 #define SILC_SF_DISCONNECTING    3 /* socket disconnecting */
100 #define SILC_SF_DISCONNECTED     4 /* socket disconnected */
101 #define SILC_SF_HOST_LOOKUP      5 /* performing host lookup for socket */
102 #define SILC_SF_DISABLED         6 /* socket connection is disabled,
103                                       no data is sent or received. */
104 #define SILC_SF_LISTENER         7
105
106 /****s* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionStruct
107  *
108  * NAME
109  * 
110  *    struct SilcSocketConnectionStruct { ... };
111  *
112  * DESCRIPTION
113  *
114  *    This object holds information about the connected sockets to the server.
115  *    This is quite important object since this is referenced by the server all
116  *    the time when figuring out what the connection is supposed to be doing
117  *    and to whom we should send a message. This structure is the structure
118  *    for the SilcSocketConnection forward declaration.
119  *
120  *    Following short description of the fields:
121  *
122  *    int sock
123  *
124  *      The actual connected socket. This is usually saved when accepting
125  *      new connection to the server.
126  *
127  *    SilcSocketType type
128  *
129  *      Type of the socket. This identifies the type of the connection. This
130  *      is mainly used to identify whether the connection is a client or a
131  *      server connection.
132  *
133  *    void *user_data
134  *
135  *      This is a pointer to a data that is is saved here at the same
136  *      time a new connection object is allocated. Usually this is a 
137  *      back-pointer to some important data for fast referencing. For
138  *      SILC server this is a pointer to the ID list and for SILC client
139  *      to object holding active connections (windows).
140  *
141  *    SilcProtocol protocol
142  *
143  *      Protocol object for the socket. Currently only one protocol can be
144  *      executing at a time for a particular socket.
145  *
146  *    SilcUInt32 flags
147  *
148  *      Socket flags that indicate the status of the socket. This can
149  *      indicate several different status that can affect the use of the
150  *      socket object.
151  *
152  *    int users
153  *
154  *      Reference counter. When allocated it is set to one (1) and it won't
155  *      be freed until it hits zero (0).
156  *
157  *    SilcSocketConnectionHB hb
158  *
159  *      The heartbeat context.  If NULL, heartbeat is not performed.
160  *
161  *    SilcBuffer inbuf
162  *    SilcBuffer outbuf
163  *
164  *      Incoming and outgoing buffers for the particular socket connection.
165  *      Incoming data from the socket is put after decryption in to the
166  *      inbuf buffer and outgoing data after encryption is put to the outbuf
167  *      buffer.
168  *
169  *    char *hostname
170  *    char *ip
171  *    SilcUInt16 port
172  *
173  *      Resolved hostname, IP address and port of the connection who owns
174  *      this object.
175  *
176  ***/
177 struct SilcSocketConnectionStruct {
178   int sock;
179   SilcSocketType type;
180   void *user_data;
181   SilcProtocol protocol;
182   SilcUInt32 flags;
183   int users;
184
185   SilcSocketConnectionHB hb;
186
187   SilcBuffer inbuf;
188   SilcBuffer outbuf;
189
190   char *hostname;
191   char *ip;
192   SilcUInt16 port;
193   SilcUInt8 sock_error;
194   SilcUInt8 version;
195 };
196
197 /* Macros */
198
199 /* Check for specific protocol version */
200 #define SILC_PROTOCOL_VERSION(s, maj, min) (s->version == maj##min)
201
202 /* Amount of bytes to be read from the socket connection at once. */
203 #define SILC_SOCKET_READ_SIZE 16384
204
205 /* Default socket buffer size. */
206 #define SILC_SOCKET_BUF_SIZE 1024
207
208 /* Generic manipulation of flags */
209 #define SF_SET(x, f) (x)->flags |= (1L << (f))
210 #define SF_UNSET(x, f) (x)->flags &= ~(1L << (f))
211 #define SF_IS(x, f) ((x)->flags & (1L << (f)))
212
213 /* Setting/Unsetting flags */
214 #define SILC_SET_OUTBUF_PENDING(x) SF_SET((x), SILC_SF_OUTBUF_PENDING)
215 #define SILC_SET_INBUF_PENDING(x) SF_SET((x), SILC_SF_INBUF_PENDING)
216 #define SILC_SET_DISCONNECTING(x) SF_SET((x), SILC_SF_DISCONNECTING)
217 #define SILC_SET_DISCONNECTED(x) SF_SET((x), SILC_SF_DISCONNECTED)
218 #define SILC_SET_HOST_LOOKUP(x) SF_SET((x), SILC_SF_HOST_LOOKUP)
219 #define SILC_SET_DISABLED(x) SF_SET((x), SILC_SF_DISABLED)
220 #define SILC_SET_LISTENER(x) SF_SET((x), SILC_SF_LISTENER)
221 #define SILC_UNSET_OUTBUF_PENDING(x) SF_UNSET((x), SILC_SF_OUTBUF_PENDING)
222 #define SILC_UNSET_INBUF_PENDING(x) SF_UNSET((x), SILC_SF_INBUF_PENDING)
223 #define SILC_UNSET_DISCONNECTING(x) SF_UNSET((x), SILC_SF_DISCONNECTING)
224 #define SILC_UNSET_DISCONNECTED(x) SF_UNSET((x), SILC_SF_DISCONNECTED)
225 #define SILC_UNSET_HOST_LOOKUP(x) SF_UNSET((x), SILC_SF_HOST_LOOKUP)
226 #define SILC_UNSET_DISABLED(x) SF_UNSET((x), SILC_SF_DISABLED)
227 #define SILC_UNSET_LISTENER(x) SF_UNSET((x), SILC_SF_LISTENER)
228
229 /* Checking for flags */
230 #define SILC_IS_OUTBUF_PENDING(x) SF_IS((x), SILC_SF_OUTBUF_PENDING)
231 #define SILC_IS_INBUF_PENDING(x) SF_IS((x), SILC_SF_INBUF_PENDING)
232 #define SILC_IS_DISCONNECTING(x) SF_IS((x), SILC_SF_DISCONNECTING)
233 #define SILC_IS_DISCONNECTED(x) SF_IS((x), SILC_SF_DISCONNECTED)
234 #define SILC_IS_HOST_LOOKUP(x) SF_IS((x), SILC_SF_HOST_LOOKUP)
235 #define SILC_IS_DISABLED(x) SF_IS((x), SILC_SF_DISABLED)
236 #define SILC_IS_LISTENER(x) SF_IS((x), SILC_SF_LISTENER)
237
238 /* Prototypes */
239
240 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_alloc
241  *
242  * SYNOPSIS
243  *
244  *    void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
245  *                           SilcSocketConnection *new_socket);
246  *
247  * DESCRIPTION
248  *
249  *    Allocates a new socket connection object. The allocated object is 
250  *    returned to the new_socket argument. The `sock' is the socket
251  *    for the connection, the `type' the initial type of the connection and
252  *    the `user_data' a application specific pointer.
253  *
254  ***/
255 void silc_socket_alloc(int sock, SilcSocketType type, void *user_data,
256                        SilcSocketConnection *new_socket);
257
258 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_free
259  *
260  * SYNOPSIS
261  *
262  *    void silc_socket_free(SilcSocketConnection sock);
263  *
264  * DESCRIPTION
265  *
266  *    Frees the socket connection context. This frees it only if the
267  *    reference counter of the socket is zero, otherwise it decreases the
268  *    reference counter.
269  *
270  ***/
271 void silc_socket_free(SilcSocketConnection sock);
272
273 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_dup
274  *
275  * SYNOPSIS
276  *
277  *    SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
278  *
279  * DESCRIPTION
280  *
281  *    Duplicates the socket context. This actually does not duplicate
282  *    any data, instead this increases the reference counter of the
283  *    context. The reference counter is decreased by calling the
284  *    silc_socket_free function and it frees the data when the counter
285  *    hits zero.
286  *
287  ***/
288 SilcSocketConnection silc_socket_dup(SilcSocketConnection sock);
289
290 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_read
291  *
292  * SYNOPSIS
293  *
294  *    int silc_socket_read(SilcSocketConnection sock);
295  *
296  * DESCRIPTION
297  *
298  *    Reads data from the socket connection into the incoming data buffer.
299  *    It reads as much as possible from the socket connection. This returns
300  *    amount of bytes read or -1 on error or -2 on case where all of the
301  *    data could not be read at once. Implementation of this function
302  *    may be platform specific.
303  *
304  ***/
305 int silc_socket_read(SilcSocketConnection sock);
306
307 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_write
308  *
309  * SYNOPSIS
310  *
311  *    int silc_socket_write(SilcSocketConnection sock);
312  *
313  * DESCRIPTION
314  *
315  *    Writes data from the outgoing buffer to the socket connection. If the
316  *    data cannot be written at once, it must be written at later time. 
317  *    The data is written from the data section of the buffer, not from head
318  *    or tail section. This automatically pulls the data section towards end
319  *    after writing the data. Implementation of this function may be
320  *    platform specific.
321  *
322  ***/
323 int silc_socket_write(SilcSocketConnection sock);
324
325 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_get_error
326  *
327  * SYNOPSIS
328  *
329  *    bool silc_socket_get_error(SilcSocketConnection sock, char *error,
330  *                               SilcUInt32 error_len);
331  *
332  * DESCRIPTION
333  *
334  *    Returns human readable error message into the `error' buffer if
335  *    the socket is in error status.  Returns TRUE if error message was
336  *    written into the buffer and FALSE if there is not socket error.
337  *
338  ***/
339 bool silc_socket_get_error(SilcSocketConnection sock, char *error,
340                            SilcUInt32 error_len);
341
342 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb
343  *
344  * SYNOPSIS
345  *
346  *    typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
347  *                                             void *context);
348  *
349  * DESCRIPTION
350  *
351  *    Heartbeat callback function. This is the function in the application
352  *    that this library will call when it is time to send the keepalive
353  *    packet SILC_PACKET_HEARTBEAT.
354  *
355  ***/
356 typedef void (*SilcSocketConnectionHBCb)(SilcSocketConnection sock,
357                                          void *context);
358
359 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_set_heartbeat
360  *
361  * SYNOPSIS
362  *
363  *    void silc_socket_set_heartbeat(SilcSocketConnection sock, 
364  *                                   SilcUInt32 heartbeat,
365  *                                   void *hb_context,
366  *                                   SilcSocketConnectionHBCb hb_callback,
367  *                                   SilcSchedule schedule);
368  *
369  * DESCRIPTION
370  *
371  *    Sets the heartbeat timeout and prepares the socket for performing
372  *    heartbeat in `heartbeat' intervals (seconds). The `hb_context' is
373  *    allocated by the application and will be sent as argument to the
374  *    `hb_callback' function that is called when the `heartbeat' timeout
375  *    expires.  The callback `hb_context' won't be touched by the library
376  *    but and must be freed by the application.  The `schedule' is the
377  *    application's scheduler.
378  *
379  ***/
380 void silc_socket_set_heartbeat(SilcSocketConnection sock, 
381                                SilcUInt32 heartbeat,
382                                void *hb_context,
383                                SilcSocketConnectionHBCb hb_callback,
384                                SilcSchedule schedule);
385
386 /****f* silcutil/SilcSocketConnectionAPI/SilcSocketHostLookupCb
387  *
388  * SYNOPSIS
389  *
390  *    typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
391  *                                           void *context);
392  *
393  * DESCRIPTION
394  *
395  *    Asynchronous host lookup callback function that will be called
396  *    when the lookup is performed.
397  *
398  ***/
399 typedef void (*SilcSocketHostLookupCb)(SilcSocketConnection sock,
400                                        void *context);
401
402 /****f* silcutil/SilcSocketConnectionAPI/silc_socket_host_lookup
403  *
404  * SYNOPSIS
405  *
406  *    void silc_socket_host_lookup(SilcSocketConnection sock,
407  *                                 bool port_lookup,
408  *                                 SilcSocketHostLookupCb callback,
409  *                                 void *context,
410  *                                 SilcSchedule schedule);
411  *
412  * DESCRIPTION
413  *
414  *    Performs asynchronous host name and IP address lookups for the
415  *    specified socket connection. This may be called when the socket
416  *    connection is created and the full IP address and fully qualified
417  *    domain name information is desired. The `callback' with `context'
418  *    will be called after the lookup is performed. The `schedule'
419  *    is the application's scheduler which the lookup routine needs. 
420  *    If the socket connection is freed during the lookup the library
421  *    will automatically cancel the lookup and the `callback' will not be
422  *    called.
423  *
424  *    If `port_lookup' is TRUE then the remote port of the socket 
425  *    connection is resolved. After the information is resolved they
426  *    are accessible using sock->ip and sock->hostname pointers. Note
427  *    that if the both IP and FQDN could not be resolved the sock->hostname
428  *    includes the IP address of the remote host. The resolved port is 
429  *    available in sock->port.
430  *
431  ***/
432 void silc_socket_host_lookup(SilcSocketConnection sock,
433                              bool port_lookup,
434                              SilcSocketHostLookupCb callback,
435                              void *context,
436                              SilcSchedule schedule);
437
438 #endif