Added SILC Server library.
[silc.git] / lib / silcutil / silcsocketstream.c
index e3521a1f48d3c65f3ccdc0cb3487a78997be111d..e67678497ad964d66ece1505023e1870b78ef2a8 100644 (file)
@@ -17,7 +17,9 @@
 
 */
 
-#include "silcincludes.h"
+#include "silc.h"
+
+/************************** Types and definitions ***************************/
 
 #define SILC_IS_SOCKET_STREAM(s) (s->ops == &silc_socket_stream_ops)
 
@@ -28,7 +30,7 @@ int silc_socket_stream_read(SilcStream stream, unsigned char *buf,
                            SilcUInt32 buf_len);
 int silc_socket_stream_write(SilcStream stream, const unsigned char *data,
                             SilcUInt32 data_len);
-bool silc_socket_stream_close(SilcStream stream);
+SilcBool silc_socket_stream_close(SilcStream stream);
 void silc_socket_stream_destroy(SilcStream stream);
 
 /* Internal async host lookup context. */
@@ -42,6 +44,9 @@ typedef struct {
   unsigned int aborted      : 1;
 } *SilcSocketHostLookup;
 
+
+/************************ Static utility functions **************************/
+
 /* The IO process callback that calls the notifier callback to upper
    layer. */
 
@@ -94,16 +99,6 @@ SILC_TASK_CALLBACK(silc_socket_host_lookup_finish)
     stream = lookup->stream = NULL;
   }
 
-  /* Add the socket to scheduler */
-  if (stream) {
-    silc_schedule_task_add_fd(stream->schedule, stream->sock,
-                             silc_socket_stream_io, stream);
-
-    /* Initially set socket for reading */
-    silc_schedule_set_listen_fd(stream->schedule, stream->sock,
-                               SILC_TASK_READ, FALSE);
-  }
-
   /* Return the created socket stream to the caller */
   if (lookup->callback)
     lookup->callback(lookup->status, stream, lookup->context);
@@ -163,10 +158,13 @@ static void silc_socket_host_lookup_abort(SilcAsyncOperation op,
   lookup->aborted = TRUE;
 }
 
+
+/******************************* Public API *********************************/
+
 /* Creates socket stream */
 
 SilcAsyncOperation
-silc_socket_stream_create(int sock, bool lookup, bool require_fqdn,
+silc_socket_stream_create(int sock, SilcBool lookup, SilcBool require_fqdn,
                          SilcSchedule schedule,
                          SilcSocketStreamCallback callback,
                          void *context)
@@ -227,9 +225,9 @@ silc_socket_stream_create(int sock, bool lookup, bool require_fqdn,
 
 /* Returns socket stream information */
 
-bool silc_socket_stream_get_info(SilcStream stream,
-                                int *sock, const char **hostname,
-                                const char **ip, SilcUInt16 *port)
+SilcBool silc_socket_stream_get_info(SilcStream stream,
+                                    int *sock, const char **hostname,
+                                    const char **ip, SilcUInt16 *port)
 {
   SilcSocketStream socket_stream = stream;
 
@@ -250,9 +248,9 @@ bool silc_socket_stream_get_info(SilcStream stream,
 
 /* Set socket information */
 
-bool silc_socket_stream_set_info(SilcStream stream,
-                                const char *hostname,
-                                const char *ip, SilcUInt16 port)
+SilcBool silc_socket_stream_set_info(SilcStream stream,
+                                    const char *hostname,
+                                    const char *ip, SilcUInt16 port)
 {
   SilcSocketStream socket_stream = stream;
 
@@ -291,11 +289,11 @@ int silc_socket_stream_get_error(SilcStream stream)
 
 /* Set QoS for socket stream */
 
-bool silc_socket_stream_set_qos(SilcStream stream,
-                               SilcUInt32 read_rate,
-                               SilcUInt32 read_limit_bytes,
-                               SilcUInt32 limit_sec,
-                               SilcUInt32 limit_usec)
+SilcBool silc_socket_stream_set_qos(SilcStream stream,
+                                   SilcUInt32 read_rate,
+                                   SilcUInt32 read_limit_bytes,
+                                   SilcUInt32 limit_sec,
+                                   SilcUInt32 limit_usec)
 {
   SilcSocketStream socket_stream = stream;
 
@@ -337,7 +335,7 @@ bool silc_socket_stream_set_qos(SilcStream stream,
 
 /* Closes socket */
 
-bool silc_socket_stream_close(SilcStream stream)
+SilcBool silc_socket_stream_close(SilcStream stream)
 {
   SilcSocketStream socket_stream = stream;
 
@@ -362,6 +360,7 @@ void silc_socket_stream_destroy(SilcStream stream)
   silc_socket_stream_close(socket_stream);
   silc_free(socket_stream->ip);
   silc_free(socket_stream->hostname);
+  silc_schedule_task_del_by_fd(socket_stream->schedule, socket_stream->sock);
 
   if (socket_stream->qos) {
     silc_schedule_task_del_by_context(socket_stream->schedule,
@@ -380,6 +379,7 @@ void silc_socket_stream_destroy(SilcStream stream)
 /* Sets stream notification callback for the stream */
 
 void silc_socket_stream_notifier(SilcStream stream,
+                                SilcSchedule schedule,
                                 SilcStreamNotifier callback,
                                 void *context)
 {
@@ -392,6 +392,35 @@ void silc_socket_stream_notifier(SilcStream stream,
 
   socket_stream->notifier = callback;
   socket_stream->notifier_context = context;
+  socket_stream->schedule = schedule;
+
+  if (socket_stream->notifier) {
+    /* Add the socket to scheduler.  Safe to call if already added. */
+    silc_schedule_task_add_fd(socket_stream->schedule, socket_stream->sock,
+                             silc_socket_stream_io, socket_stream);
+
+    /* Initially set socket for reading */
+    silc_schedule_set_listen_fd(socket_stream->schedule, socket_stream->sock,
+                               SILC_TASK_READ, FALSE);
+  } else {
+    /* Unschedule the socket */
+    silc_schedule_unset_listen_fd(socket_stream->schedule,
+                                 socket_stream->sock);
+    silc_schedule_task_del_by_fd(socket_stream->schedule,
+                                socket_stream->sock);
+  }
+}
+
+/* Return associated scheduler */
+
+SilcSchedule silc_socket_stream_get_schedule(SilcStream stream)
+{
+  SilcSocketStream socket_stream = stream;
+
+  if (!SILC_IS_SOCKET_STREAM(socket_stream))
+    return NULL;
+
+  return socket_stream->schedule;
 }
 
 /* SILC Socket Stream ops.  Functions are implemented under the
@@ -403,4 +432,5 @@ const SilcStreamOps silc_socket_stream_ops =
   silc_socket_stream_close,
   silc_socket_stream_destroy,
   silc_socket_stream_notifier,
+  silc_socket_stream_get_schedule,
 };