1 /*
2 
3   silcsocketstream.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 2005 - 2007 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 
20 /****h* silcutil/SILC Socket Stream Interface
21  *
22  * DESCRIPTION
23  *
24  * Implementation of SILC Socket Stream.  SILC Socket Stream can be used
25  * read data from and write data to a socket connection.  The SILC Socket
26  * Stream provides also Quality of Service (QoS) support that can be used
27  * to control the throughput of the stream.  It also supports both TCP and
28  * UDP, and IPv4 and IPv6.
29  *
30  * SILC Socket Stream is not thread-safe.  If the same socket stream must be
31  * used in multithreaded environment concurrency control must be employed.
32  *
33  ***/
34 
35 #ifndef SILCSOCKETSTREAM_H
36 #define SILCSOCKETSTREAM_H
37 
38 /****d* silcutil/SilcSocketStreamAPI/SilcSocketStreamStatus
39  *
40  * NAME
41  *
42  *    typedef enum { ... } SilcStreamStatus;
43  *
44  * DESCRIPTION
45  *
46  *    Socket Stream status.  This status is returned into the
47  *    SilcSocketStreamCallback function after the socket stream is
48  *    created.
49  *
50  * SOURCE
51  */
52 typedef enum {
53   SILC_SOCKET_OK,		/* Normal status */
54   SILC_SOCKET_UNKNOWN_IP,	/* Remote does not have IP address */
55   SILC_SOCKET_UNKNOWN_HOST,	/* Remote does not have host name */
56   SILC_SOCKET_NO_MEMORY,	/* System out of memory */
57   SILC_SOCKET_ERROR,		/* Unknown error */
58 } SilcSocketStreamStatus;
59 /***/
60 
61 /****f* silcutil/SilcSocketStreamAPI/SilcSocketStreamCallback
62  *
63  * SYNOPSIS
64  *
65  *    typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
66  *                                             SilcStream stream,
67  *                                             void *context);
68  *
69  * DESCRIPTION
70  *
71  *    Callback function of this type is called after the socket stream
72  *    creation is completed.  If the `stream' is NULL the socket stream could
73  *    not be created or the socket connection is not otherwise allowed.  The
74  *    `status' will indicate the error status.  In case error ocurrs the
75  *    associated socket has already been destroyed.  The `stream' is socket
76  *    stream representing the socket connection and silc_socket_stream_*
77  *    functions can be used to access the stream.  All other silc_stream_*
78  *    functions can also be used to read data, send data, and otherwise
79  *    handle the stream.
80  *
81  *    If the silc_stream_set_notifier is called the stream will be set to
82  *    non-blocking mode.
83  *
84  ***/
85 typedef void (*SilcSocketStreamCallback)(SilcSocketStreamStatus status,
86 					 SilcStream stream, void *context);
87 
88 /****f* silcutil/SilcSocketStreamAPI/silc_socket_tcp_stream_create
89  *
90  * SYNOPSIS
91  *
92  *    SilcAsyncOperation
93  *    silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
94  *                                  SilcBool require_fqdn,
95  *                                  SilcSchedule schedule,
96  *                                  SilcSocketStreamCallback callback,
97  *                                  void *context);
98  *
99  * DESCRIPTION
100  *
101  *    Creates TCP socket stream of the TCP connection indicated by `sock'.
102  *    The stream can be destroyed by calling the silc_stream_destroy.  Data
103  *    can be sent and received from the stream by calling silc_stream_write
104  *    and silc_stream_read.  The creation process is asynchronous since
105  *    socket connection information, such as hostname and IP address are
106  *    resolved, so SilcAsyncOperation is returned which can be used to cancel
107  *    the creation process.  The `callback' will be called to return the
108  *    created socket stream.
109  *
110  *    If the `lookup' is TRUE then this will perform IP and hostname lookup
111  *    for the socket.  If the `require_fqdn' is TRUE then the socket must
112  *    have valid hostname and IP address, otherwise the stream creation will
113  *    fail.  If it is FALSE then only valid IP address is required.  Note that,
114  *    if the `lookup' is FALSE then the hostname, IP and port information
115  *    will not be available from the socket stream.  In that case this will
116  *    also return NULL as the `callback' is called immediately.
117  *
118  *    If the silc_stream_set_notifier is called the stream is set to
119  *    non-blocking mode.
120  *
121  ***/
122 SilcAsyncOperation
123 silc_socket_tcp_stream_create(SilcSocket sock, SilcBool lookup,
124 			      SilcBool require_fqdn,
125 			      SilcSchedule schedule,
126 			      SilcSocketStreamCallback callback,
127 			      void *context);
128 
129 /****f* silcutil/SilcSocketStreamAPI/silc_socket_udp_stream_create
130  *
131  * SYNOPSIS
132  *
133  *    SilcStream silc_socket_udp_stream_create(SilcSocket sock,
134  *                                             SilcBool ipv6,
135  *                                             SilcBool connected,
136  *                                             SilcSchedule schedule);
137  *
138  * DESCRIPTION
139  *
140  *    Creates UDP socket stream of the UDP connection indicated by `sock'.
141  *    The stream can be destroyed by calling the silc_stream_destroy.
142  *    The `connected' defines whether the socket is in connected or in
143  *    connectionless state.
144  *
145  *    Note that, UDP packets may be read only through the notifier
146  *    callback (see silc_stream_set_notifier), when SILC_STREAM_CAN_READ
147  *    is returned to the callback.  Because of this the notifier callback
148  *    must be set.
149  *
150  *    Note that, UDP packet sending using silc_stream_write and receiving
151  *    with silc_stream_read works only if the `sock' is a UDP socket in a
152  *    connected state.  In connectionless state sending packets with
153  *    silc_stream_write is possible only if the remote address and port
154  *    has been set with silc_socket_stream_set_info.  If it is not set
155  *    in connectionless state packets may be sent only by using the
156  *    silc_net_udp_send function.  In connectionless state packets may be
157  *    received only by using silc_net_udp_receive.
158  *
159  *    This function returns the created SilcStream or NULL on error.
160  *
161  *    If the silc_stream_set_notifier is called the stream is set to
162  *    non-blocking mode.
163  *
164  ***/
165 SilcStream silc_socket_udp_stream_create(SilcSocket sock,
166 					 SilcBool ipv6,
167 					 SilcBool connected,
168 					 SilcSchedule schedule);
169 
170 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_is_udp
171  *
172  * SYNOPSIS
173  *
174  *    SilcBool silc_socket_stream_is_udp(SilcStream stream,
175  *                                       SilcBool *connected);
176  *
177  * DESCRIPTION
178  *
179  *    Returns TRUE if the `stream' is UDP stream.  If the `connected' pointer
180  *    is non-NULL it will have indication whether the UDP stream is in
181  *    connected state.  If it is then packets can be read and written using
182  *    silc_stream_read and silc_stream_write.  If it is not then packets
183  *    need to read and written by using silc_net_udp_receive and
184  *    silc_net_udp_send.
185  *
186  ***/
187 SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected);
188 
189 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_get_info
190  *
191  * SYNOPSIS
192  *
193  *    SilcBool
194  *    silc_socket_stream_get_info(SilcStream stream,
195  *                                SilcSocket *sock, const char **hostname,
196  *                                const char **ip, SilcUInt16 *port);
197  *
198  * DESCRIPTION
199  *
200  *    Returns socket stream information such as the socket, remote hostname,
201  *    remote IP address and the remote port of the remote socket connection.
202  *    Return FALSE if these informations are not available.
203  *
204  ***/
205 SilcBool silc_socket_stream_get_info(SilcStream stream,
206 				     SilcSocket *sock, const char **hostname,
207 				     const char **ip, SilcUInt16 *port);
208 
209 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_set_info
210  *
211  * SYNOPSIS
212  *
213  *    SilcBool
214  *    silc_socket_stream_set_info(SilcStream stream,
215  *                                const char *hostname,
216  *                                const char *ip, SilcUInt16 port);
217  *
218  * DESCRIPTION
219  *
220  *    Use this function to set the hostname, IP address and remote port
221  *    information to the socket stream indicated by `stream' if you did not
222  *    perform lookup in the silc_socket_tcp_stream_create.  This is not
223  *    mandatory but if you would like to associate the information with the
224  *    stream use this function.  If the lookup was performed when creating
225  *    the stream then calling this function is not necessary.  Use the
226  *    function silc_socket_stream_get_info to get the information from the
227  *    stream.
228  *
229  ***/
230 SilcBool silc_socket_stream_set_info(SilcStream stream,
231 				     const char *hostname,
232 				     const char *ip, SilcUInt16 port);
233 
234 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_get_error
235  *
236  * SYNOPSIS
237  *
238  *    int silc_socket_stream_get_error(SilcStream stream);
239  *
240  * DESCRIPTION
241  *
242  *    If error occurred during socket stream operations, this function
243  *    can be used to retrieve the error number that occurred.
244  *
245  ***/
246 int silc_socket_stream_get_error(SilcStream stream);
247 
248 /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_set_qos
249  *
250  * SYNOPSIS
251  *
252  *    SilcBool silc_socket_stream_set_qos(SilcStream stream,
253  *                                        SilcUInt32 read_rate,
254  *                                        SilcUInt32 read_limit_bytes,
255  *                                        SilcUInt32 limit_sec,
256  *                                        SilcUInt32 limit_usec)
257  *
258  * DESCRIPTION
259  *
260  *    Sets a "Quality of Service" settings for socket stream `stream'.
261  *    The `read_rate' specifies the maximum read operations per second.
262  *    If more read operations are executed the limit will be applied for
263  *    the reading.  The `read_limit_bytes' specifies the maximum data
264  *    that is read.  It is guaranteed that silc_stream_read  never returns
265  *    more than `read_limit_bytes' of data.  The `limit_sec' and `limit_usec'
266  *    specifies the time limit that is applied if `read_rate' and/or
267  *    `read_limit_bytes' is reached.  If all arguments except `stream'
268  *    are zero this resets the QoS from the socket stream, all QoS for
269  *    this socket stream that may be pending will be cancelled.
270  *
271  ***/
272 SilcBool silc_socket_stream_set_qos(SilcStream stream,
273 				    SilcUInt32 read_rate,
274 				    SilcUInt32 read_limit_bytes,
275 				    SilcUInt32 limit_sec,
276 				    SilcUInt32 limit_usec);
277 
278 #include "silcsocketstream_i.h"
279 
280 #endif /* SILCSOCKETSTREAM_H */
281