From: Pekka Riikonen Date: Sun, 3 Dec 2006 20:49:35 +0000 (+0000) Subject: Handle UDP socket stream correctly. X-Git-Tag: silc.client.1.1.beta1~145 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=3d893ff20583885f1357646e4a4fe3a951cef245;p=silc.git Handle UDP socket stream correctly. Added silc_socket_stream_is_udp. --- diff --git a/lib/silcutil/silcsocketstream.c b/lib/silcutil/silcsocketstream.c index c1d838cd..1bd6b8b3 100644 --- a/lib/silcutil/silcsocketstream.c +++ b/lib/silcutil/silcsocketstream.c @@ -22,6 +22,7 @@ /************************** Types and definitions ***************************/ #define SILC_IS_SOCKET_STREAM(s) (s->ops == &silc_socket_stream_ops) +#define SILC_IS_SOCKET_STREAM_UDP(s) (s->ops == &silc_socket_udp_stream_ops) const SilcStreamOps silc_socket_stream_ops; const SilcStreamOps silc_socket_udp_stream_ops; @@ -232,6 +233,7 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, /* Creates UDP socket stream */ SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6, + SilcBool connected, SilcSchedule schedule) { SilcSocketStream stream; @@ -246,10 +248,26 @@ SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6, stream->sock = sock; stream->schedule = schedule; stream->ipv6 = ipv6; + stream->connected = connected; return (SilcStream)stream; } +/* Returns TRUE if the stream is UDP stream */ + +SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected) +{ + SilcSocketStream socket_stream = stream; + + if (!SILC_IS_SOCKET_STREAM_UDP(socket_stream)) + return FALSE; + + if (connected) + *connected = socket_stream->connected; + + return TRUE; +} + /* Returns socket stream information */ SilcBool silc_socket_stream_get_info(SilcStream stream, @@ -258,7 +276,8 @@ SilcBool silc_socket_stream_get_info(SilcStream stream, { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return FALSE; if (sock) @@ -290,7 +309,8 @@ SilcBool silc_socket_stream_set_info(SilcStream stream, { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return FALSE; if (hostname) { @@ -322,7 +342,8 @@ int silc_socket_stream_get_error(SilcStream stream) { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return 0; return socket_stream->sock_error; @@ -338,7 +359,8 @@ SilcBool silc_socket_stream_set_qos(SilcStream stream, { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return FALSE; SILC_LOG_DEBUG(("Setting QoS for socket stream")); @@ -380,7 +402,8 @@ SilcBool silc_socket_stream_close(SilcStream stream) { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return FALSE; silc_schedule_unset_listen_fd(socket_stream->schedule, socket_stream->sock); @@ -395,7 +418,8 @@ void silc_socket_stream_destroy(SilcStream stream) { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return; silc_socket_stream_close(socket_stream); @@ -428,7 +452,8 @@ void silc_socket_stream_notifier(SilcStream stream, { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return; SILC_LOG_DEBUG(("Setting stream notifier callback")); @@ -462,7 +487,8 @@ SilcSchedule silc_socket_stream_get_schedule(SilcStream stream) { SilcSocketStream socket_stream = stream; - if (!SILC_IS_SOCKET_STREAM(socket_stream)) + if (!SILC_IS_SOCKET_STREAM(socket_stream) && + !SILC_IS_SOCKET_STREAM_UDP(socket_stream)) return NULL; return socket_stream->schedule; diff --git a/lib/silcutil/silcsocketstream.h b/lib/silcutil/silcsocketstream.h index f135ca54..e03c3255 100644 --- a/lib/silcutil/silcsocketstream.h +++ b/lib/silcutil/silcsocketstream.h @@ -124,12 +124,15 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, * SYNOPSIS * * SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6, + * SilcBool connected, * SilcSchedule schedule); * * DESCRIPTION * * Creates UDP socket stream of the UDP connection indicated by `sock'. * The stream can be destroyed by calling the silc_stream_destroy. + * The `connected' defines whether the socket is in connected or in + * connectionless state. * * Note that, UDP packets may be read only through the notifier * callback (see silc_stream_set_notifier), when SILC_STREAM_CAN_READ @@ -138,16 +141,38 @@ silc_socket_tcp_stream_create(int sock, SilcBool lookup, * * Note that, UDP packet sending using silc_stream_write and receiving * with silc_stream_read works only if the `sock' is a UDP socket in a - * connected state. If it is not the silc_net_udp_send function and - * silc_net_udp_receive functions must be used. The SILC_STREAM_CAN_WRITE - * is never returned to the notifier callback. + * connected state. In connectionless state sending packets with + * silc_stream_write is possible only if the remote address and port + * has been set with silc_socket_stream_set_info. If it is not set + * in connectionless state packets may be sent only by using the + * silc_net_udp_send function. In connectionless state packets may be + * received only by using silc_net_udp_receive. * * This function returns the created SilcStream or NULL on error. * ***/ SilcStream silc_socket_udp_stream_create(int sock, SilcBool ipv6, + SilcBool connected, SilcSchedule schedule); +/****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_get_info + * + * SYNOPSIS + * + * SilcBool silc_socket_stream_is_udp(SilcStream stream, + * SilcBool *connected); + * + * DESCRIPTION + * + * Returns TRUE if the `stream' is UDP stream. If the `connected' pointer + * is non-NULL indication whether the UDP stream is in connected state. + * If it is then packets can be read and written using silc_stream_read + * and silc_stream_write. If it is not then packets need to read and + * written by using silc_net_udp_receive and silc_net_udp_send. + * + ***/ +SilcBool silc_socket_stream_is_udp(SilcStream stream, SilcBool *connected); + /****f* silcutil/SilcSocketStreamAPI/silc_socket_stream_get_info * * SYNOPSIS diff --git a/lib/silcutil/silcsocketstream_i.h b/lib/silcutil/silcsocketstream_i.h index 46c5ef29..73547ea2 100644 --- a/lib/silcutil/silcsocketstream_i.h +++ b/lib/silcutil/silcsocketstream_i.h @@ -52,7 +52,8 @@ struct SilcSocketStreamStruct { SilcSocketQos qos; SilcStreamNotifier notifier; void *notifier_context; - unsigned int ipv6 : 1; + unsigned int ipv6 : 1; /* UDP IPv6 */ + unsigned int connected : 1; /* UDP connected state */ }; #endif /* SILCSOCKETSTREAM_I_H */