Configurable lookup for network listener creation.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 14 Sep 2006 20:05:19 +0000 (20:05 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 14 Sep 2006 20:05:19 +0000 (20:05 +0000)
lib/silcutil/silcfdstream.c
lib/silcutil/silcnet.h
lib/silcutil/silcnet_i.h
lib/silcutil/silcschedule.c
lib/silcutil/unix/silcunixnet.c

index db9bd9d724185d0396b454b5857d301eb7790c84..a5ce7b8747189c6f4dfcdcec0cc01b9f2b03eaca 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 Pekka Riikonen
+  Copyright (C) 2005 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -19,6 +19,8 @@
 
 #include "silc.h"
 
+/************************** Types and definitions ***************************/
+
 #define SILC_IS_FD_STREAM(s) (s->ops == &silc_fd_stream_ops)
 
 const SilcStreamOps silc_fd_stream_ops;
@@ -34,6 +36,9 @@ typedef struct {
   int error;
 } *SilcFDStream;
 
+
+/************************ Static utility functions **************************/
+
 /* The IO process callback that calls the notifier callback to upper layer. */
 
 SILC_TASK_CALLBACK(silc_fd_stream_io)
@@ -57,6 +62,9 @@ SILC_TASK_CALLBACK(silc_fd_stream_io)
   }
 }
 
+
+/****************************** Public API **********************************/
+
 /* Create file descriptor stream */
 
 SilcStream silc_fd_stream_create(int fd)
index b5bbd2d4e62845db6e049a724a1c77fa19d123ea..6e7d35ed9836781de8f5281ca07382be7508aaef 100644 (file)
@@ -109,8 +109,8 @@ typedef void (*SilcNetCallback)(SilcNetStatus status,
  *
  *    SilcNetListener
  *    silc_net_tcp_create_listener(const char **local_ip_addr,
- *                                 SilcUInt32 local_ip_count,
- *                                 int port, SilcBool require_fqdn,
+ *                                 SilcUInt32 local_ip_count, int port,
+ *                                 SilcBool lookup, SilcBool require_fqdn,
  *                                 SilcSchedule schedule,
  *                                 SilcNetCallback callback, void *context);
  *
@@ -123,13 +123,14 @@ typedef void (*SilcNetCallback)(SilcNetStatus status,
  *    `local_ip_count' many IP addresses provided in `local_ip_addr' table.
  *    On success returns the SilcNetListener context, or NULL on error.
  *    If `require_fqdn' is TRUE the listener will require that the incoming
- *    connection has FQDN to be able to connect.
+ *    connection has FQDN to be able to connect.  If the `lookup' is TRUE
+ *    then the incoming connection hostname will be resolved.
  *
  ***/
 SilcNetListener
 silc_net_tcp_create_listener(const char **local_ip_addr,
-                            SilcUInt32 local_ip_count,
-                            int port, SilcBool require_fqdn,
+                            SilcUInt32 local_ip_count, int port,
+                            SilcBool lookup, SilcBool require_fqdn,
                             SilcSchedule schedule,
                             SilcNetCallback callback, void *context);
 
index 1da16a97e016492b98408163ce2c80419697e4a4..7cc356e20e2b450ccda83b846d60915ad51adf8b 100644 (file)
@@ -30,8 +30,9 @@ struct SilcNetListenerStruct {
   SilcNetCallback callback;
   void *context;
   int *socks;
-  unsigned int socks_count   : 31;
+  unsigned int socks_count   : 30;
   unsigned int require_fqdn  : 1;
+  unsigned int lookup        : 1;
 };
 
 #endif /* SILCNET_I_H */
index d60b6d30c1905dcf669750eaafb98056ef91aca0..50c6f5ddbcb80ba4234be43d4fea910d0e1870d5 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "silc.h"
 
+/************************** Types and definitions ***************************/
+
 /* Platform specific implementation */
 extern const SilcScheduleOps schedule_ops;
 
@@ -28,6 +30,9 @@ static void silc_schedule_dispatch_fd(SilcSchedule schedule);
 static void silc_schedule_dispatch_timeout(SilcSchedule schedule,
                                           SilcBool dispatch_all);
 
+
+/************************ Static utility functions **************************/
+
 /* Fd task hash table destructor */
 
 static void silc_schedule_fd_destructor(void *key, void *context,
@@ -36,94 +41,6 @@ static void silc_schedule_fd_destructor(void *key, void *context,
   silc_free(context);
 }
 
-/* Initializes the scheduler. This returns the scheduler context that
-   is given as arugment usually to all silc_schedule_* functions.
-   The `max_tasks' indicates the number of maximum tasks that the
-   scheduler can handle. The `app_context' is application specific
-   context that is delivered to task callbacks. */
-
-SilcSchedule silc_schedule_init(int max_tasks, void *app_context)
-{
-  SilcSchedule schedule;
-
-  SILC_LOG_DEBUG(("Initializing scheduler"));
-
-  schedule = silc_calloc(1, sizeof(*schedule));
-  if (!schedule)
-    return NULL;
-
-  schedule->fd_queue =
-    silc_hash_table_alloc(0, silc_hash_uint, NULL, NULL, NULL,
-                         silc_schedule_fd_destructor, NULL, TRUE);
-  if (!schedule->fd_queue)
-    return NULL;
-
-  silc_list_init(schedule->timeout_queue, struct SilcTaskTimeoutStruct, next);
-
-  schedule->app_context = app_context;
-  schedule->valid = TRUE;
-  schedule->max_tasks = max_tasks;
-
-  /* Allocate scheduler lock */
-  silc_mutex_alloc(&schedule->lock);
-
-  /* Initialize the platform specific scheduler. */
-  schedule->internal = schedule_ops.init(schedule, app_context);
-
-  return schedule;
-}
-
-/* Uninitializes the schedule. This is called when the program is ready
-   to end. This removes all tasks and task queues. Returns FALSE if the
-   scheduler could not be uninitialized. This happens when the scheduler
-   is still valid and silc_schedule_stop has not been called. */
-
-SilcBool silc_schedule_uninit(SilcSchedule schedule)
-{
-  SILC_LOG_DEBUG(("Uninitializing scheduler"));
-
-  if (schedule->valid == TRUE)
-    return FALSE;
-
-  /* Dispatch all timeouts before going away */
-  SILC_SCHEDULE_LOCK(schedule);
-  silc_schedule_dispatch_timeout(schedule, TRUE);
-  SILC_SCHEDULE_UNLOCK(schedule);
-
-  /* Deliver signals before going away */
-  if (schedule->signal_tasks) {
-    schedule_ops.signals_call(schedule, schedule->internal);
-    schedule->signal_tasks = FALSE;
-  }
-
-  /* Unregister all tasks */
-  silc_schedule_task_remove(schedule, SILC_ALL_TASKS);
-  silc_schedule_task_remove(schedule, SILC_ALL_TASKS);
-
-  /* Unregister all task queues */
-  silc_hash_table_free(schedule->fd_queue);
-
-  /* Uninit the platform specific scheduler. */
-  schedule_ops.uninit(schedule, schedule->internal);
-
-  silc_mutex_free(schedule->lock);
-  silc_free(schedule);
-
-  return TRUE;
-}
-
-/* Stops the schedule even if it is not supposed to be stopped yet.
-   After calling this, one should call silc_schedule_uninit (after the
-   silc_schedule has returned). */
-
-void silc_schedule_stop(SilcSchedule schedule)
-{
-  SILC_LOG_DEBUG(("Stopping scheduler"));
-  SILC_SCHEDULE_LOCK(schedule);
-  schedule->valid = FALSE;
-  SILC_SCHEDULE_UNLOCK(schedule);
-}
-
 /* Executes file descriptor tasks. Invalid tasks are removed here. */
 
 static void silc_schedule_dispatch_fd(SilcSchedule schedule)
@@ -277,6 +194,146 @@ static void silc_schedule_select_timeout(SilcSchedule schedule)
   }
 }
 
+/* Removes task from the scheduler.  This must be called with scheduler
+   locked. */
+
+static void silc_schedule_task_remove(SilcSchedule schedule, SilcTask task)
+{
+  SilcTaskFd ftask;
+  SilcTaskTimeout ttask;
+
+  if (task == SILC_ALL_TASKS) {
+    SilcTask task;
+    SilcHashTableList htl;
+    SilcUInt32 fd;
+
+    /* Delete from fd queue */
+    silc_hash_table_list(schedule->fd_queue, &htl);
+    while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task))
+      silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(fd));
+    silc_hash_table_list_reset(&htl);
+
+    /* Delete from timeout queue */
+    silc_list_start(schedule->timeout_queue);
+    while ((task = (SilcTask)silc_list_get(schedule->timeout_queue))
+          != SILC_LIST_END) {
+      silc_list_del(schedule->timeout_queue, task);
+      silc_free(task);
+    }
+
+    return;
+  }
+
+  /* Delete from timeout queue */
+  if (task->type == 1) {
+    silc_list_start(schedule->timeout_queue);
+    while ((ttask = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
+      if (ttask == (SilcTaskTimeout)task) {
+       silc_list_del(schedule->timeout_queue, ttask);
+       silc_free(ttask);
+       break;
+      }
+    }
+
+    return;
+  }
+
+  /* Delete from fd queue */
+  ftask = (SilcTaskFd)task;
+  silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(ftask->fd));
+}
+
+
+/****************************** Public API **********************************/
+
+/* Initializes the scheduler. This returns the scheduler context that
+   is given as arugment usually to all silc_schedule_* functions.
+   The `max_tasks' indicates the number of maximum tasks that the
+   scheduler can handle. The `app_context' is application specific
+   context that is delivered to task callbacks. */
+
+SilcSchedule silc_schedule_init(int max_tasks, void *app_context)
+{
+  SilcSchedule schedule;
+
+  SILC_LOG_DEBUG(("Initializing scheduler"));
+
+  schedule = silc_calloc(1, sizeof(*schedule));
+  if (!schedule)
+    return NULL;
+
+  schedule->fd_queue =
+    silc_hash_table_alloc(0, silc_hash_uint, NULL, NULL, NULL,
+                         silc_schedule_fd_destructor, NULL, TRUE);
+  if (!schedule->fd_queue)
+    return NULL;
+
+  silc_list_init(schedule->timeout_queue, struct SilcTaskTimeoutStruct, next);
+
+  schedule->app_context = app_context;
+  schedule->valid = TRUE;
+  schedule->max_tasks = max_tasks;
+
+  /* Allocate scheduler lock */
+  silc_mutex_alloc(&schedule->lock);
+
+  /* Initialize the platform specific scheduler. */
+  schedule->internal = schedule_ops.init(schedule, app_context);
+
+  return schedule;
+}
+
+/* Uninitializes the schedule. This is called when the program is ready
+   to end. This removes all tasks and task queues. Returns FALSE if the
+   scheduler could not be uninitialized. This happens when the scheduler
+   is still valid and silc_schedule_stop has not been called. */
+
+SilcBool silc_schedule_uninit(SilcSchedule schedule)
+{
+  SILC_LOG_DEBUG(("Uninitializing scheduler"));
+
+  if (schedule->valid == TRUE)
+    return FALSE;
+
+  /* Dispatch all timeouts before going away */
+  SILC_SCHEDULE_LOCK(schedule);
+  silc_schedule_dispatch_timeout(schedule, TRUE);
+  SILC_SCHEDULE_UNLOCK(schedule);
+
+  /* Deliver signals before going away */
+  if (schedule->signal_tasks) {
+    schedule_ops.signals_call(schedule, schedule->internal);
+    schedule->signal_tasks = FALSE;
+  }
+
+  /* Unregister all tasks */
+  silc_schedule_task_remove(schedule, SILC_ALL_TASKS);
+  silc_schedule_task_remove(schedule, SILC_ALL_TASKS);
+
+  /* Unregister all task queues */
+  silc_hash_table_free(schedule->fd_queue);
+
+  /* Uninit the platform specific scheduler. */
+  schedule_ops.uninit(schedule, schedule->internal);
+
+  silc_mutex_free(schedule->lock);
+  silc_free(schedule);
+
+  return TRUE;
+}
+
+/* Stops the schedule even if it is not supposed to be stopped yet.
+   After calling this, one should call silc_schedule_uninit (after the
+   silc_schedule has returned). */
+
+void silc_schedule_stop(SilcSchedule schedule)
+{
+  SILC_LOG_DEBUG(("Stopping scheduler"));
+  SILC_SCHEDULE_LOCK(schedule);
+  schedule->valid = FALSE;
+  SILC_SCHEDULE_UNLOCK(schedule);
+}
+
 /* Runs the scheduler once and then returns. */
 
 SilcBool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
@@ -636,55 +693,6 @@ void silc_schedule_task_del_by_all(SilcSchedule schedule, int fd,
   SILC_SCHEDULE_UNLOCK(schedule);
 }
 
-/* Removes task from the scheduler.  This must be called with scheduler
-   locked. */
-
-static void silc_schedule_task_remove(SilcSchedule schedule, SilcTask task)
-{
-  SilcTaskFd ftask;
-  SilcTaskTimeout ttask;
-
-  if (task == SILC_ALL_TASKS) {
-    SilcTask task;
-    SilcHashTableList htl;
-    SilcUInt32 fd;
-
-    /* Delete from fd queue */
-    silc_hash_table_list(schedule->fd_queue, &htl);
-    while (silc_hash_table_get(&htl, (void **)&fd, (void **)&task))
-      silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(fd));
-    silc_hash_table_list_reset(&htl);
-
-    /* Delete from timeout queue */
-    silc_list_start(schedule->timeout_queue);
-    while ((task = (SilcTask)silc_list_get(schedule->timeout_queue))
-          != SILC_LIST_END) {
-      silc_list_del(schedule->timeout_queue, task);
-      silc_free(task);
-    }
-
-    return;
-  }
-
-  /* Delete from timeout queue */
-  if (task->type == 1) {
-    silc_list_start(schedule->timeout_queue);
-    while ((ttask = silc_list_get(schedule->timeout_queue)) != SILC_LIST_END) {
-      if (ttask == (SilcTaskTimeout)task) {
-       silc_list_del(schedule->timeout_queue, ttask);
-       silc_free(ttask);
-       break;
-      }
-    }
-
-    return;
-  }
-
-  /* Delete from fd queue */
-  ftask = (SilcTaskFd)task;
-  silc_hash_table_del(schedule->fd_queue, SILC_32_TO_PTR(ftask->fd));
-}
-
 /* Sets a file descriptor to be listened by scheduler. One can call this
    directly if wanted. This can be called multiple times for one file
    descriptor to set different iomasks. */
index 7bb5b6c5cef2574b2db41039c6ca7e9082a1c946..929ecf38ce3d5e80be811393258fc4b3bfffb873 100644 (file)
@@ -112,7 +112,8 @@ SILC_TASK_CALLBACK(silc_net_accept)
   silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
 
   /* Create socket stream */
-  silc_socket_tcp_stream_create(sock, TRUE, listener->require_fqdn, schedule,
+  silc_socket_tcp_stream_create(sock, listener->lookup,
+                               listener->require_fqdn, schedule,
                                silc_net_accept_stream, listener);
 }
 
@@ -120,8 +121,8 @@ SILC_TASK_CALLBACK(silc_net_accept)
 
 SilcNetListener
 silc_net_tcp_create_listener(const char **local_ip_addr,
-                            SilcUInt32 local_ip_count,
-                            int port, SilcBool require_fqdn,
+                            SilcUInt32 local_ip_count, int port,
+                            SilcBool lookup, SilcBool require_fqdn,
                             SilcSchedule schedule,
                             SilcNetCallback callback, void *context)
 {
@@ -143,6 +144,8 @@ silc_net_tcp_create_listener(const char **local_ip_addr,
   listener->schedule = schedule;
   listener->callback = callback;
   listener->context = context;
+  listener->require_fqdn = require_fqdn;
+  listener->lookup = lookup;
 
   if (local_ip_count > 0) {
     listener->socks = silc_calloc(local_ip_count, sizeof(*listener->socks));