Handle UDP socket stream correctly.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 3 Dec 2006 20:49:35 +0000 (20:49 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 3 Dec 2006 20:49:35 +0000 (20:49 +0000)
Added silc_socket_stream_is_udp.

lib/silcutil/silcsocketstream.c
lib/silcutil/silcsocketstream.h
lib/silcutil/silcsocketstream_i.h

index c1d838cd581ea37437de9e3dd2b9c7f5413c9f34..1bd6b8b32144b79c18b25048db5f23640fae0555 100644 (file)
@@ -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;
index f135ca54755a618ad9dbab2386ebcfa9f90d0b3b..e03c3255542fe5979b8d7a8f6941cde3d88afcfd 100644 (file)
@@ -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
index 46c5ef2921ab8ed2c8db94515e5ce51ebbb7f601..73547ea27d8d766a64b51d962a363e2b63b538bc 100644 (file)
@@ -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 */