Added UDP network support.
[silc.git] / lib / silcutil / silcnet.h
1 /*
2
3   silcnet.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2006 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 Net Interface
21  *
22  * DESCRIPTION
23  *
24  * SILC Net API provides various network routines for applications. It
25  * can be used to create TCP/IP and UDP/IP connections and listeners.
26  * Various utility functions for resolving various information is also
27  * provided.
28  *
29  * On WIN32 systems the SILC Net API must initialized by calling the
30  * silc_net_win32_init and uninitialized when the application ends by
31  * calling the silc_net_win32_uninit function. The initializing must be
32  * done in order to assure that the SILC Net API works correctly.
33  *
34  ***/
35
36 #ifndef SILCNET_H
37 #define SILCNET_H
38
39 /* Prototypes */
40
41 /****s* silcutil/SilcNetAPI/SilcNetListener
42  *
43  * NAME
44  *
45  *    typedef struct SilcNetListenerStruct *SilcNetListener;
46  *
47  * DESCRIPTION
48  *
49  *    The network listenr context.  This context is created with the
50  *    silc_net_create_listener function and destroyed with
51  *    silc_net_close_listener function.
52  *
53  ***/
54 typedef struct SilcNetListenerStruct *SilcNetListener;
55
56 /****d* silcutil/SilcNetAPI/SilcNetStatus
57  *
58  * NAME
59  *
60  *    typedef enum { ... } SilcNetStatus;
61  *
62  * DESCRIPTION
63  *
64  *    Status to indicate the result of the network operation creation.  This
65  *    type is returned in the SilcNetCallback callback function.
66  *
67  * SOURCE
68  */
69 typedef enum {
70   SILC_NET_OK,                         /* Everything Ok */
71   SILC_NET_UNKNOWN_IP,                 /* Unknown IP address */
72   SILC_NET_UNKNOWN_HOST,               /* Unknown hostname */
73   SILC_NET_HOST_UNREACHABLE,           /* Destination unreachable */
74   SILC_NET_CONNECTION_REFUSED,         /* Connection refused */
75   SILC_NET_CONNECTION_TIMEOUT,         /* Connection timedout */
76   SILC_NET_NO_MEMORY,                  /* System out of memory */
77   SILC_NET_ERROR,                      /* Unknown error */
78 } SilcNetStatus;
79 /***/
80
81 /****f* silcutil/SilcNetAPI/SilcNetCallback
82  *
83  * SYNOPSIS
84  *
85  *    typedef void (*SilcNetCallback)(SilcNetStatus status,
86  *                                    SilcStream stream, void *context);
87  *
88  * DESCRIPTION
89  *
90  *    A callback of this type is returned by silc_net_tcp_create_listener,
91  *    silc_net_udp_create_listener, silc_net_tcp_connect and
92  *    silc_net_udp_connect functions.  For silc_net_tcp_create_listener
93  *    and silc_net_udp_create_listener this callback means that new incoming
94  *    connection was accepted, and the `stream' is the socket stream
95  *    representing the socket connection.
96  *
97  *    For silc_net_tcp_connect and silc_net_udp_connect this means that we
98  *    have connected to the remote host and the `stream' is the socket
99  *    stream for the socket connection.  The SILC Stream API (such as
100  *    silc_stream_read, etc.) can be used to read and write to the stream.
101  *    The created stream is socket stream so various SilcSocketStream API
102  *    functions can be used with the `stream'.
103  *
104  ***/
105 typedef void (*SilcNetCallback)(SilcNetStatus status,
106                                 SilcStream stream, void *context);
107
108 /****f* silcutil/SilcNetAPI/silc_net_tcp_create_listener
109  *
110  * SYNOPSIS
111  *
112  *    SilcNetListener
113  *    silc_net_tcp_create_listener(const char **local_ip_addr,
114  *                                 SilcUInt32 local_ip_count,
115  *                                 int port, SilcBool require_fqdn,
116  *                                 SilcSchedule schedule,
117  *                                 SilcNetCallback callback, void *context);
118  *
119  * DESCRIPTION
120  *
121  *    This function creates TCP listener etc.  This is used to create network
122  *    listener for incoming connections, and `callback' will be called
123  *    everytime new connection is received.  If `local_ip_addr' is NULL any
124  *    address is used.  If provided it can be used bind the listener to
125  *    `local_ip_count' many IP addresses provided in `local_ip_addr' table.
126  *    On success returns the SilcNetListener context, or NULL on error.
127  *    If `require_fqdn' is TRUE the listener will require that the incoming
128  *    connection has FQDN to be able to connect.
129  *
130  ***/
131 SilcNetListener
132 silc_net_tcp_create_listener(const char **local_ip_addr,
133                              SilcUInt32 local_ip_count,
134                              int port, SilcBool require_fqdn,
135                              SilcSchedule schedule,
136                              SilcNetCallback callback, void *context);
137
138 /****f* silcutil/SilcNetAPI/silc_net_close_listener
139  *
140  * SYNOPSIS
141  *
142  *    void silc_net_close_listener(SilcNetListener listener);
143  *
144  * DESCRIPTION
145  *
146  *    Closes the network listener indicated by `listener'.
147  *
148  ***/
149 void silc_net_close_listener(SilcNetListener listener);
150
151 /****f* silcutil/SilcNetAPI/silc_net_tcp_connect
152  *
153  * SYNOPSIS
154  *
155  *    SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
156  *                                            const char *remote_ip_addr,
157  *                                            int remote_port,
158  *                                            SilcSchedule schedule,
159  *                                            SilcNetCallback callback,
160  *                                            void *context);
161  *
162  * DESCRIPTION
163  *
164  *    Creates TCP/IP connection to the remote host indicated by `remote_host'
165  *    which may be hostname or IP address, on the port indicated by
166  *    `remote_port'.  If the `local_ip_addr' is provided the local host is
167  *    bound to that address before creating the connection.  This is
168  *    asynchronous call, and this function returns before the connection is
169  *    actually established.  The `callback' will be called after the
170  *    connection is created to deliver the SilcStream for the created
171  *    connection.
172  *
173  *    The returned SilcAsyncOperation context can be used to control the
174  *    asynchronous connecting, such as to abort it.  If it is aborted
175  *    using silc_async_abort the `callback' will not be called.  If NULL
176  *    is returned the operation cannot be aborted and the `callback' will
177  *    be called eventually.
178  *
179  */
180 SilcAsyncOperation silc_net_tcp_connect(const char *local_ip_addr,
181                                         const char *remote_ip_addr,
182                                         int remote_port,
183                                         SilcSchedule schedule,
184                                         SilcNetCallback callback,
185                                         void *context);
186
187 /****f* silcutil/SilcNetAPI/silc_net_udp_connect
188  *
189  * SYNOPSIS
190  *
191  *    SilcStream
192  *    silc_net_udp_connect(const char *local_ip_addr, int local_port,
193  *                         const char *remote_ip_addr, int remote_port,
194  *                         SilcSchedule schedule);
195  *
196  * DESCRIPTION
197  *
198  *    This function creates UDP stream.  The UDP stream is bound to the
199  *    `local_ip_addr' if it is specified.  The `local_port' must always be
200  *    specified.  If the `remote_ip_addr' and `remote_port' is also provided,
201  *    packets may be sent to that address using silc_stream_write function
202  *    and packets may be received using silc_stream_read function.
203  *
204  *    If the remote address is not provided then packets may only be received
205  *    by using silc_net_udp_receive and sent only by using the function
206  *    silc_net_udp_send.
207  *
208  *    To receive packets the silc_stream_set_notifier must be called for the
209  *    returned SilcStream.  The packets are always received in the notifier
210  *    callback when the SILC_STREAM_CAN_READ is returned to the callback
211  *    To read the packet use silc_stream_read if the remote address was
212  *    provided, and silc_net_udp_receive if it was not.
213  *
214  * EXAMPLE
215  *
216  *    SilcStream udpstream;
217  *
218  *    // Create UDP stream and prepare to receive packets
219  *    udpstream = silc_net_udp_connect("10.2.1.7", 5000,
220  *                                     "10.2.1.100, 5000, schedule);
221  *    silc_stream_set_notifier(udpstream, schedule, receive_callback, context);
222  *
223  *    // Send packet to remote host
224  *    silc_stream_write(udpstream, data, data_len);
225  *
226  ***/
227 SilcStream
228 silc_net_udp_connect(const char *local_ip_addr, int local_port,
229                      const char *remote_ip_addr, int remote_port,
230                      SilcSchedule schedule);
231
232 /****f* silcutil/SilcNetAPI/silc_net_udp_receive
233  *
234  * SYNOPSIS
235  *
236  *    int
237  *    silc_net_udp_receive(SilcStream stream, char *remote_ip_addr,
238  *                         SilcUInt32 remote_ip_addr_size, int *remote_port,
239  *                         unsigned char *ret_data, SilcUInt32 data_size)
240  *
241  * DESCRIPTION
242  *
243  *    Receive a UDP packet from the `stream'.  The IP address and port of
244  *    the sender is returned into `remote_ip_addr' buffer and `remote_port'
245  *    pointer.  The packet data is returned into the `ret_data' buffer.
246  *
247  *    Returns the length of the packet, or -1 on error or 0 in case of EOF.
248  *
249  ***/
250 int silc_net_udp_receive(SilcStream stream, char *remote_ip_addr,
251                          SilcUInt32 remote_ip_addr_size, int *remote_port,
252                          unsigned char *ret_data, SilcUInt32 data_size);
253
254 /****f* silcutil/SilcNetAPI/silc_net_udp_send
255  *
256  * SYNOPSIS
257  *
258  *    void silc_net_udp_send(SilcStream stream,
259  *                           const char *remote_ip_addr, int remote_port,
260  *                           const unsigned char *data, SilcUInt32 data_len);
261  *
262  * DESCRIPTION
263  *
264  *    Sends an UDP packet to remote host `remote_ip_addr' on `remote_port'.
265  *    This may be used with UDP streams that are not connected to any
266  *    specific remote host.  With those stream silc_stream_write cannot be
267  *    used.  In those cases, this function must be used.  This may also be
268  *    used even if the stream is connected.
269  *
270  *    This function always succeeds, however there is no guarantee that the
271  *    packet is delivered, as UDP is unreliable transport protocol.
272  *
273  ***/
274 void silc_net_udp_send(SilcStream stream,
275                        const char *remote_ip_addr, int remote_port,
276                        const unsigned char *data, SilcUInt32 data_len);
277
278 /****f* silcutil/SilcNetAPI/silc_net_close_connection
279  *
280  * SYNOPSIS
281  *
282  *    void silc_net_close_connection(int sock);
283  *
284  * DESCRIPTION
285  *
286  *    Closes the connection by closing the socket connection.
287  *
288  ***/
289 void silc_net_close_connection(int sock);
290
291 /****f* silcutil/SilcNetAPI/silc_net_accept_connection
292  *
293  * SYNOPSIS
294  *
295  *    int silc_net_accept_connection(int sock);
296  *
297  * DESCRIPTION
298  *
299  *    Accepts a connection from a particular socket.
300  *
301  ***/
302 int silc_net_accept_connection(int sock);
303
304 /****f* silcutil/SilcNetAPI/silc_net_set_socket_nonblock
305  *
306  * SYNOPSIS
307  *
308  *    int silc_net_set_socket_nonblock(int sock);
309  *
310  * DESCRIPTION
311  *
312  *    Sets the socket to non-blocking mode.
313  *
314  ***/
315 int silc_net_set_socket_nonblock(int sock);
316
317 /****f* silcutil/SilcNetAPI/silc_net_set_socket_opt
318  *
319  * SYNOPSIS
320  *
321  *    int silc_net_set_socket_opt(int sock, int level, int option, int on);
322  *
323  * DESCRIPTION
324  *
325  *    Sets a option for a socket.  This function can be used to set
326  *    various options for the socket.  Some of the options might be
327  *    system specific.
328  *
329  ***/
330 int silc_net_set_socket_opt(int sock, int level, int option, int on);
331
332 /****f* silcutil/SilcNetAPI/silc_net_get_socket_opt
333  *
334  * SYNOPSIS
335  *
336  *    int silc_net_get_socket_opt(int sock, int level, int option,
337  *                                void *optval, int *opt_len);
338  *
339  * DESCRIPTION
340  *
341  *    Return socket options to the `optval' and `opt_len'.
342  *
343  ***/
344 int silc_net_get_socket_opt(int sock, int level, int option,
345                             void *optval, int *opt_len);
346
347 /****f* silcutil/SilcNetAPI/silc_net_is_ip4
348  *
349  * SYNOPSIS
350  *
351  *    SilcBool silc_net_is_ip4(const char *addr);
352  *
353  * DESCRIPTION
354  *
355  *    Checks whether IP address sent as argument is valid IPv4 address.
356  *
357  ***/
358 SilcBool silc_net_is_ip4(const char *addr);
359
360 /****f* silcutil/SilcNetAPI/silc_net_is_ip6
361  *
362  * SYNOPSIS
363  *
364  *    SilcBool silc_net_is_ip6(const char *addr);
365  *
366  * DESCRIPTION
367  *
368  *    Checks whether IP address sent as argument is valid IPv6 address.
369  *
370  ***/
371 SilcBool silc_net_is_ip6(const char *addr);
372
373 /****f* silcutil/SilcNetAPI/silc_net_is_ip
374  *
375  * SYNOPSIS
376  *
377  *    SilcBool silc_net_is_ip(const char *addr);
378  *
379  * DESCRIPTION
380  *
381  *    Checks whether IP address sent as argument is valid IP address.
382  *    This supports both IPv4 and IPv6 addresses.
383  *
384  ***/
385 SilcBool silc_net_is_ip(const char *addr);
386
387 /****f* silcutil/SilcNetAPI/silc_net_addr2bin
388  *
389  * SYNOPSIS
390  *
391  *    SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len);
392  *
393  * DESCRIPTION
394  *
395  *    Converts the IP number string from numbers-and-dots notation to
396  *    binary form in network byte order.  The address can be either
397  *    IPv4 or IPv6 address.
398  *
399  ***/
400 SilcBool silc_net_addr2bin(const char *addr, void *bin, SilcUInt32 bin_len);
401
402 /****f* silcutil/SilcNetAPI/SilcNetResolveCallback
403  *
404  * SYNOPSIS
405  *
406  *    typedef void (*SilcNetResolveCallback)(const char *result,
407  *                                           void *context);
408  *
409  * DESCRIPTION
410  *
411  *    A callback function of this type is called after the asynchronous
412  *    resolving operation has been completed.  This callback is used
413  *    when asynchronously resolving IP addresses and hostnames.
414  *
415  ***/
416 typedef void (*SilcNetResolveCallback)(const char *result, void *context);
417
418 /****f* silcutil/SilcNetAPI/silc_net_gethostbyname
419  *
420  * SYNOPSIS
421  *
422  *    SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6,
423  *                                char *address, SilcUInt32 address_len);
424  *
425  * DESCRIPTION
426  *
427  *    Resolves the IP address of the hostname indicated by the `name'.
428  *    This returns TRUE and the IP address of the host to the `address'
429  *    buffer, or FALSE if the address could not be resolved.  This is
430  *    synchronous function and will block the calling process.  If the
431  *    `prefer_ipv6' is TRUE then this will return IPv6 address if it
432  *    finds.  If FALSE if returns IPv4 address even if it found IPv6
433  *    address also.
434  *
435  ***/
436 SilcBool silc_net_gethostbyname(const char *name, SilcBool prefer_ipv6,
437                                 char *address, SilcUInt32 address_len);
438
439 /****f* silcutil/SilcNetAPI/silc_net_gethostbyname_async
440  *
441  * SYNOPSIS
442  *
443  *    void silc_net_gethostbyname_async(const char *name,
444  *                                      SilcBool prefer_ipv6,
445  *                                      SilcSchedule schedule,
446  *                                      SilcNetResolveCallback completion,
447  *                                      void *context)
448  *
449  * DESCRIPTION
450  *
451  *    Asynchronously resolves the IP address of the hostname indicated
452  *    by the `name'.  This function returns immediately, and the
453  *    `completion' callback will be called after the resolving is
454  *    completed.
455  *
456  *    If the `prefer_ipv6' is TRUE then this will return IPv6 address if it
457  *    finds.  If FALSE if returns IPv4 address even if it found IPv6
458  *    address also.
459  *
460  ***/
461 void silc_net_gethostbyname_async(const char *name,
462                                   SilcBool prefer_ipv6,
463                                   SilcSchedule schedule,
464                                   SilcNetResolveCallback completion,
465                                   void *context);
466
467 /****f* silcutil/SilcNetAPI/silc_net_gethostbyaddr
468  *
469  * SYNOPSIS
470  *
471  *   SilcBool silc_net_gethostbyaddr(const char *addr, char *name,
472  *                               SilcUInt32 name_len);
473  *
474  * DESCRIPTION
475  *
476  *    Resolves the hostname for the IP address indicated by the `addr'
477  *    This returns TRUE and the resolved hostname to the `name' buffer,
478  *    or FALSE on error. The `addr' may be either IPv4 or IPv6 address.
479  *    This is synchronous function and will block the calling process.
480  *
481  ***/
482 SilcBool silc_net_gethostbyaddr(const char *addr, char *name,
483                                 SilcUInt32 name_len);
484
485 /****f* silcutil/SilcNetAPI/silc_net_gethostbyaddr_async
486  *
487  * SYNOPSIS
488  *
489  *    void silc_net_gethostbyaddr_async(const char *addr,
490  *                                      SilcSchedule schedule,
491  *                                      SilcNetResolveCallback completion,
492  *                                      void *context)
493  *
494  * DESCRIPTION
495  *
496  *    Asynchronously resolves the hostname for the IP address indicated
497  *    by the `addr'.  This function returns immediately, and the
498  *    `completion' callback will be called after the resolving is
499  *    completed.
500  *
501  ***/
502 void silc_net_gethostbyaddr_async(const char *addr,
503                                   SilcSchedule schedule,
504                                   SilcNetResolveCallback completion,
505                                   void *context);
506
507 /****f* silcutil/SilcNetAPI/silc_net_check_host_by_sock
508  *
509  * SYNOPSIS
510  *
511  *    SilcBool silc_net_check_host_by_sock(int sock, char **hostname,
512  *                                         char **ip);
513  *
514  * DESCRIPTION
515  *
516  *    Performs lookups for remote name and IP address. This peforms reverse
517  *    lookup as well to verify that the IP has FQDN.
518  *
519  ***/
520 SilcBool silc_net_check_host_by_sock(int sock, char **hostname, char **ip);
521
522 /****f* silcutil/SilcNetAPI/silc_net_check_local_by_sock
523  *
524  * SYNOPSIS
525  *
526  *    SilcBool silc_net_check_local_by_sock(int sock, char **hostname,
527  *                                          char **ip);
528  *
529  * DESCRIPTION
530  *
531  *    Performs lookups for local name and IP address. This peforms reverse
532  *    lookup as well to verify that the IP has FQDN.
533  *
534  ***/
535 SilcBool silc_net_check_local_by_sock(int sock, char **hostname, char **ip);
536
537 /****f* silcutil/SilcNetAPI/silc_net_get_remote_port
538  *
539  * SYNOPSIS
540  *
541  *    SilcUInt16 silc_net_get_remote_port(int sock);
542  *
543  * DESCRIPTION
544  *
545  *    Return remote port by socket.
546  *
547  ***/
548 SilcUInt16 silc_net_get_remote_port(int sock);
549
550 /****f* silcutil/SilcNetAPI/silc_net_get_local_port
551  *
552  * SYNOPSIS
553  *
554  *    SilcUInt16 silc_net_get_local_port(int sock);
555  *
556  * DESCRIPTION
557  *
558  *    Return local port by socket.
559  *
560  ***/
561 SilcUInt16 silc_net_get_local_port(int sock);
562
563 /****f* silcutil/SilcNetAPI/silc_net_localhost
564  *
565  * SYNOPSIS
566  *
567  *    char *silc_net_localhost(void);
568  *
569  * DESCRIPTION
570  *
571  *    Return name of localhost.  This will also attempt to resolve
572  *    the real hostname by the local host's IP address.  If unsuccessful
573  *    the first found hostname is returned.  The caller must free
574  *    returned hostname.
575  *
576  ***/
577 char *silc_net_localhost(void);
578
579 /****f* silcutil/SilcNetAPI/silc_net_localip
580  *
581  * SYNOPSIS
582  *
583  *    char *silc_net_localip(void)
584  *
585  * DESCRIPTION
586  *
587  *    Return IP of localhost.  The caller must free the returned IP.
588  *
589  ***/
590 char *silc_net_localip(void);
591
592 /****f* silcutil/SilcNetAPI/silc_net_win32_init
593  *
594  * SYNOPSIS
595  *
596  *    SilcBool silc_net_win32_init(void);
597  *
598  * DESCRIPTION
599  *
600  *    This is WIN32 system specific function and is used to initialize
601  *    the network.  This must be called by all WIN32 applications.  It
602  *    is usually called at the application's main() or WinMain() before
603  *    calling any other SILC routine.  The application must also call
604  *    the silc_net_win32_uninit when exiting the application.  Returns
605  *    FALSE on error.  The network will not work if this function returns
606  *    FALSE.
607  *
608  * NOTES
609  *
610  *    This routines is available only on Win32 platform.
611  *
612  ***/
613 SilcBool silc_net_win32_init(void);
614
615 /****f* silcutil/SilcNetAPI/silc_net_win32_uninit
616  *
617  * SYNOPSIS
618  *
619  *    void silc_net_win32_init(void);
620  *
621  * DESCRIPTION
622  *
623  *    This is WIN32 system specific function and is used to uninitialize
624  *    the network.  This must be called by all WIN32 applications.  It
625  *    is usually called when the application is exiting.  After calling
626  *    this function the SILC Net API routines will not work anymore.
627  *
628  * NOTES
629  *
630  *    This routines is available only on Win32 platform.
631  *
632  ***/
633 void silc_net_win32_uninit(void);
634
635 #include "silcnet_i.h"
636
637 #endif /* SILCNET_H */