updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 9 Jul 2001 15:43:12 +0000 (15:43 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 9 Jul 2001 15:43:12 +0000 (15:43 +0000)
CHANGES
TODO
apps/silcd/server.c
lib/silcutil/silcschedule.c
lib/silcutil/unix/silcunixthread.c

diff --git a/CHANGES b/CHANGES
index a33e236849fcacceaa386d03b5d7110b61c96114..278ea542dcf3d7158bfea8ccd42fd17bf7559d4d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+Mon Jul  9 18:28:34 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * The server now performs the incoming host IP/DNS lookup
+         using the silc_socket_host_lookup and thus does not block
+         the server anymore.  Affected file silcd/server.c.
+
 Mon Jul  9 13:40:03 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Added new function silc_schedule_wakeup that is used in
diff --git a/TODO b/TODO
index bcdeaa2e64101287970343f11709117fe51fc910..745a026bbdae379e44680795d6d74c7bfe06d77b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -60,11 +60,6 @@ TODO/bugs In SILC Server
 
        o silcd/serverid.c and its routines supports only IPv4.
 
- o DNS/IP lookup blocks the server.  This must be fixed.  Check the
-   resolver stuff (resolver(3), resolver(5)).  Either we have to do the
-   own resolver stuff (through scheduler, if possible without writing
-   too much own stuff) or use threads.
-
  o The backup router support described in the protocol specification
    should be done at some point.
 
index 1160f10bbab9d9ad9e123ef517fbeba77511555d..707e1d2d385beb1dfb2f656fd54517528da5562e 100644 (file)
@@ -931,87 +931,58 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final)
   sock->protocol = NULL;
 }
 
-/* Accepts new connections to the server. Accepting new connections are
-   done in three parts to make it async. */
-
-SILC_TASK_CALLBACK(silc_server_accept_new_connection)
+/* Host lookup callbcak that is called after the incoming connection's
+   IP and FQDN lookup is performed. This will actually check the acceptance
+   of the incoming connection and will register the key exchange protocol
+   for this connection. */
+
+static void 
+silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
+                                        void *context)
 {
   SilcServer server = (SilcServer)context;
-  SilcSocketConnection newsocket;
   SilcServerKEInternalContext *proto_ctx;
-  int sock, port;
   void *cconfig, *sconfig, *rconfig;
   SilcServerConfigSectionDenyConnection *deny;
+  int port;
 
-  SILC_LOG_DEBUG(("Accepting new connection"));
-
-  server->stat.conn_attempts++;
-
-  sock = silc_net_accept_connection(server->sock);
-  if (sock < 0) {
-    SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
-    server->stat.conn_failures++;
-    return;
-  }
+  SILC_LOG_DEBUG(("Start"));
 
-  /* Check max connections */
-  if (sock > SILC_SERVER_MAX_CONNECTIONS) {
-    SILC_LOG_ERROR(("Refusing connection, server is full"));
+  /* Check whether we could resolve both IP and FQDN. */
+  if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
+                   server->params->require_reverse_mapping)) {
+    SILC_LOG_ERROR(("IP/DNS lookup failed %s",
+                   sock->hostname ? sock->hostname :
+                   sock->ip ? sock->ip : ""));
     server->stat.conn_failures++;
+    silc_server_disconnect_remote(server, sock,
+                                 "Server closed connection: Unknown host");
     return;
   }
 
-  /* Set socket options */
-  silc_net_set_socket_nonblock(sock);
-  silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
-
-  /* We don't create a ID yet, since we don't know what type of connection
-     this is yet. But, we do add the connection to the socket table. */
-  silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
-  server->sockets[sock] = newsocket;
-
-  /* XXX This MUST be done async as this will block the entire server
-     process. Either we have to do our own resolver stuff or in the future
-     we can use threads. */
-  /* Perform name and address lookups for the remote host. */
-  if (!silc_net_check_host_by_sock(sock, &newsocket->hostname, 
-                                  &newsocket->ip)) {
-    if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
-       !newsocket->ip) {
-      SILC_LOG_ERROR(("IP/DNS lookup failed %s",
-                     newsocket->hostname ? newsocket->hostname :
-                     newsocket->ip ? newsocket->ip : ""));
-      server->stat.conn_failures++;
-      return;
-    }
-    if (!newsocket->hostname)
-      newsocket->hostname = strdup(newsocket->ip);
-  }
-  newsocket->port = silc_net_get_remote_port(sock);
-
   /* Register the connection for network input and output. This sets
      that scheduler will listen for incoming packets for this connection 
      and sets that outgoing packets may be sent to this connection as well.
      However, this doesn't set the scheduler for outgoing traffic, it
      will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
      later when outgoing data is available. */
-  SILC_REGISTER_CONNECTION_FOR_IO(sock);
+  SILC_REGISTER_CONNECTION_FOR_IO(sock->sock);
 
-  SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
-                newsocket->ip));
+  SILC_LOG_INFO(("Incoming connection from %s (%s)", sock->hostname,
+                sock->ip));
 
-  port = server->sockets[fd]->port; /* Listenning port */
+  port = server->sockets[server->sock]->port; /* Listenning port */
 
   /* Check whether this connection is denied to connect to us. */
-  deny = silc_server_config_denied_conn(server->config, newsocket->ip, port);
+  deny = silc_server_config_denied_conn(server->config, sock->ip, port);
   if (!deny)
-    deny = silc_server_config_denied_conn(server->config, newsocket->hostname,
+    deny = silc_server_config_denied_conn(server->config, sock->hostname,
                                          port);
   if (deny) {
     /* The connection is denied */
     SILC_LOG_INFO(("Connection %s (%s) is denied", 
-                   newsocket->hostname, newsocket->ip));
-    silc_server_disconnect_remote(server, newsocket, deny->comment ?
+                   sock->hostname, sock->ip));
+    silc_server_disconnect_remote(server, sock, deny->comment ?
                                  deny->comment :
                                  "Server closed connection: "
                                  "Connection refused");
@@ -1023,23 +994,23 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
      have to check all configurations since we don't know what type of
      connection this is. */
   if (!(cconfig = silc_server_config_find_client_conn(server->config,
-                                                     newsocket->ip, port)))
+                                                     sock->ip, port)))
     cconfig = silc_server_config_find_client_conn(server->config,
-                                                 newsocket->hostname, 
+                                                 sock->hostname, 
                                                  port);
   if (!(sconfig = silc_server_config_find_server_conn(server->config,
-                                                    newsocket->ip, 
+                                                    sock->ip, 
                                                     port)))
     sconfig = silc_server_config_find_server_conn(server->config,
-                                                 newsocket->hostname,
+                                                 sock->hostname,
                                                  port);
   if (!(rconfig = silc_server_config_find_router_conn(server->config,
-                                                    newsocket->ip, port)))
+                                                    sock->ip, port)))
     rconfig = silc_server_config_find_router_conn(server->config,
-                                                 newsocket->hostname, 
+                                                 sock->hostname, 
                                                  port);
   if (!cconfig && !sconfig && !rconfig) {
-    silc_server_disconnect_remote(server, newsocket
+    silc_server_disconnect_remote(server, sock
                                  "Server closed connection: "
                                  "Connection refused");
     server->stat.conn_failures++;
@@ -1052,7 +1023,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
      sent as context for the protocol. */
   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
   proto_ctx->server = context;
-  proto_ctx->sock = newsocket;
+  proto_ctx->sock = sock;
   proto_ctx->rng = server->rng;
   proto_ctx->responder = TRUE;
   proto_ctx->cconfig = cconfig;
@@ -1065,7 +1036,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
      there before we start the protocol. */
   server->stat.auth_attempts++;
   silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, 
-                     &newsocket->protocol, proto_ctx, 
+                     &sock->protocol, proto_ctx, 
                      silc_server_accept_new_connection_second);
 
   /* Register a timeout task that will be executed if the connector
@@ -1073,13 +1044,57 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection)
      now, this is a hard coded limit. After 60 secs the connection will
      be closed if the key exchange protocol has not been started. */
   proto_ctx->timeout_task = 
-    silc_task_register(server->timeout_queue, newsocket->sock, 
+    silc_task_register(server->timeout_queue, sock->sock, 
                       silc_server_timeout_remote,
                       context, 60, 0,
                       SILC_TASK_TIMEOUT,
                       SILC_TASK_PRI_LOW);
 }
 
+/* Accepts new connections to the server. Accepting new connections are
+   done in three parts to make it async. */
+
+SILC_TASK_CALLBACK(silc_server_accept_new_connection)
+{
+  SilcServer server = (SilcServer)context;
+  SilcSocketConnection newsocket;
+  int sock;
+
+  SILC_LOG_DEBUG(("Accepting new connection"));
+
+  server->stat.conn_attempts++;
+
+  sock = silc_net_accept_connection(server->sock);
+  if (sock < 0) {
+    SILC_LOG_ERROR(("Could not accept new connection: %s", strerror(errno)));
+    server->stat.conn_failures++;
+    return;
+  }
+
+  /* Check max connections */
+  if (sock > SILC_SERVER_MAX_CONNECTIONS) {
+    SILC_LOG_ERROR(("Refusing connection, server is full"));
+    server->stat.conn_failures++;
+    return;
+  }
+
+  /* Set socket options */
+  silc_net_set_socket_nonblock(sock);
+  silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
+
+  /* We don't create a ID yet, since we don't know what type of connection
+     this is yet. But, we do add the connection to the socket table. */
+  silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
+  server->sockets[sock] = newsocket;
+
+  /* Perform asynchronous host lookup. This will lookup the IP and the
+     FQDN of the remote connection. After the lookup is done the connection
+     is accepted further. */
+  silc_socket_host_lookup(newsocket, TRUE, 
+                         silc_server_accept_new_connection_lookup, context, 
+                         server->timeout_queue);
+}
+
 /* Second part of accepting new connection. Key exchange protocol has been
    performed and now it is time to do little connection authentication
    protocol to figure out whether this connection is client or server
index 260ed50de0994be6f8cd53c3a31de8b9fafb35c5..ee1063d42917b329bfe4306bcea7cd6b0ee7e3bd 100644 (file)
@@ -18,7 +18,6 @@
 
 */
 /* $Id$ */
-/* XXX on multi-threads the task queue locking is missing here. */
 
 #include "silcincludes.h"
 
@@ -136,6 +135,7 @@ struct SilcScheduleStruct {
   int max_fd;
   void *wakeup;
   SILC_MUTEX_DEFINE(lock);
+  bool is_locked;
 };
 
 /* Initializes the scheduler. Sets the non-timeout task queue hook and
@@ -241,7 +241,9 @@ bool silc_schedule_uninit(SilcSchedule schedule)
 void silc_schedule_stop(SilcSchedule schedule)
 {
   SILC_LOG_DEBUG(("Stopping scheduler"));
+  silc_mutex_lock(schedule->lock);
   schedule->valid = FALSE;
+  silc_mutex_unlock(schedule->lock);
 }
 
 /* Sets a file descriptor to be listened by select() in scheduler. One can
@@ -286,41 +288,51 @@ void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd)
    here from the task queue. This macro is used by silc_schedule function. 
    We don't have to care about the tasks priority here because the tasks
    are sorted in their priority order already at the registration phase. */
+/* This must be called holding the schedule->lock and the
+   schedule->fd_queue->lock. */
 
 #define SILC_SCHEDULE_RUN_TASKS                                                   \
 do {                                                                      \
   queue = schedule->fd_queue;                                             \
   if (queue && queue->valid == TRUE && queue->task) {                     \
     task = queue->task;                                                           \
-                                                                          \
-    /* Walk thorugh all tasks in the particular task queue and            \
-       execute the callback functions of those tasks matching the         \
-       fd set by select(). */                                             \
-    while(1) {                                                            \
-      /* Validity of the task is checked always before and after          \
-        execution beacuse the task might have been unregistered           \
+                                                                          \
+    /* Walk thorugh all tasks in the particular task queue and            \
+       execute the callback functions of those tasks matching the         \
+       fd set by select(). */                                             \
+    while(1) {                                                            \
+      /* Validity of the task is checked always before and after          \
+        execution beacuse the task might have been unregistered           \
         in the callback function, ie. it is not valid anymore. */         \
-                                                                          \
-      if (task->valid) {                                                  \
-       /* Task ready for reading */                                       \
-       if ((FD_ISSET(task->fd, &schedule->in)) &&                         \
-           (task->iomask & (1L << SILC_TASK_READ))) {                     \
+                                                                          \
+      if (task->valid) {                                                  \
+       /* Task ready for reading */                                       \
+       if ((FD_ISSET(task->fd, &schedule->in)) &&                         \
+           (task->iomask & (1L << SILC_TASK_READ))) {                     \
+          silc_mutex_unlock(queue->lock);                                 \
+          silc_mutex_unlock(schedule->lock);                              \
          task->callback(queue, SILC_TASK_READ, task->context, task->fd);  \
-          is_run = TRUE;                                                  \
-       }                                                                  \
-      }                                                                   \
+          silc_mutex_lock(schedule->lock);                                \
+          silc_mutex_lock(queue->lock);                                           \
+          is_run = TRUE;                                                  \
+       }                                                                  \
+      }                                                                           \
                                                                           \
       if (task->valid) {                                                  \
        /* Task ready for writing */                                       \
-       if ((FD_ISSET(task->fd, &schedule->out)) &&                        \
-           (task->iomask & (1L << SILC_TASK_WRITE))) {                    \
+       if ((FD_ISSET(task->fd, &schedule->out)) &&                        \
+           (task->iomask & (1L << SILC_TASK_WRITE))) {                    \
+          silc_mutex_unlock(queue->lock);                                 \
+          silc_mutex_unlock(schedule->lock);                              \
          task->callback(queue, SILC_TASK_WRITE, task->context, task->fd); \
-          is_run = TRUE;                                                  \
-       }                                                                  \
+          silc_mutex_lock(schedule->lock);                                \
+          silc_mutex_lock(queue->lock);                                           \
+          is_run = TRUE;                                                  \
+       }                                                                  \
       }                                                                           \
                                                                           \
-      if (!task->valid) {                                                 \
-       /* Invalid (unregistered) tasks are removed from the               \
+      if (!task->valid) {                                                 \
+       /* Invalid (unregistered) tasks are removed from the               \
           task queue. */                                                  \
        if (queue->task == task->next) {                                   \
          silc_task_remove(queue, task);                                   \
@@ -328,14 +340,14 @@ do {                                                                         \
         }                                                                 \
                                                                           \
         task = task->next;                                                \
-        silc_task_remove(queue, task->prev);                              \
-        continue;                                                         \
-      }                                                                           \
-                                                                          \
-      /* Break if there isn't more tasks in the queue */                  \
-      if (queue->task == task->next)                                      \
+        silc_task_remove(queue, task->prev);                              \
+        continue;                                                         \
+      }                                                                           \
+                                                                          \
+      /* Break if there isn't more tasks in the queue */                  \
+      if (queue->task == task->next)                                      \
         break;                                                            \
-                                                                          \
+                                                                          \
       task = task->next;                                                  \
     }                                                                     \
   }                                                                       \
@@ -344,6 +356,7 @@ do {                                                                           \
 /* Selects tasks to be listened by select(). These are the non-timeout
    tasks. This checks the scheduler's fd list. This macro is used by 
    silc_schedule function. */
+/* This must be called holding schedule->lock. */
 
 #define SILC_SCHEDULE_SELECT_TASKS                             \
 do {                                                           \
@@ -371,6 +384,8 @@ do {                                                                \
    macro. This macro is used by silc_schedule function. We don't have to
    care about priorities because tasks are already sorted in their priority
    order at the registration phase. */
+/* This must be called with holding the schedule->lock and the
+   schedule->timeout_queue->lock */
 
 #define SILC_SCHEDULE_RUN_TIMEOUT_TASKS                                        \
 do {                                                                   \
@@ -386,16 +401,26 @@ do {                                                                      \
                                                                        \
         /* Task ready for reading */                                   \
         if (task->valid) {                                             \
-          if ((task->iomask & (1L << SILC_TASK_READ)))                 \
+          if ((task->iomask & (1L << SILC_TASK_READ))) {               \
+            silc_mutex_unlock(queue->lock);                            \
+            silc_mutex_unlock(schedule->lock);                         \
            task->callback(queue, SILC_TASK_READ,                       \
                           task->context, task->fd);                    \
+            silc_mutex_lock(schedule->lock);                           \
+            silc_mutex_lock(queue->lock);                              \
+          }                                                            \
        }                                                               \
                                                                        \
         /* Task ready for writing */                                   \
         if (task->valid) {                                             \
-          if ((task->iomask & (1L << SILC_TASK_WRITE)))                        \
-            task->callback(queue, SILC_TASK_WRITE,                     \
-                          task->context, task->fd);                    \
+          if ((task->iomask & (1L << SILC_TASK_WRITE))) {              \
+            silc_mutex_unlock(queue->lock);                            \
+            silc_mutex_unlock(schedule->lock);                         \
+           task->callback(queue, SILC_TASK_WRITE,                      \
+                          task->context, task->fd);                    \
+            silc_mutex_lock(schedule->lock);                           \
+            silc_mutex_lock(queue->lock);                              \
+          }                                                            \
         }                                                              \
                                                                        \
         /* Break if there isn't more tasks in the queue */             \
@@ -426,6 +451,8 @@ do {                                                                        \
    when at earliest some of the timeout tasks expire. If this is in the
    past, they will be run now. This macro is used by the silc_schedule
    function. */
+/* This must be called with holding the schedule->lock and the
+   schedule->timeout_queue->lock */
 
 #define SILC_SCHEDULE_SELECT_TIMEOUT                                       \
 do {                                                                       \
@@ -490,12 +517,13 @@ do {                                                                          \
    specific fd there wasn't other non-timeout tasks. This checks the earlier
    set fd list, thus the generic tasks apply to all specified fd's. All the
    generic tasks are executed at once. */
+/* This must be called holding the schedule->lock and the
+   schedule->generic_queue->lock. */
 
 #define SILC_SCHEDULE_RUN_GENERIC_TASKS                                             \
 do {                                                                        \
   if (is_run == FALSE) {                                                    \
     SILC_LOG_DEBUG(("Running generic tasks"));                              \
-    silc_mutex_lock(schedule->lock);                                        \
     for (i = 0; i <= schedule->fd_list.last_fd; i++)                        \
       if (schedule->fd_list.fd[i] != -1) {                                  \
                                                                             \
@@ -520,20 +548,24 @@ do {                                                                           \
              if (task->valid && schedule->fd_list.fd[i] != -1) {            \
                /* Task ready for reading */                                 \
                if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_READ))) {    \
+                  silc_mutex_unlock(queue->lock);                           \
                   silc_mutex_unlock(schedule->lock);                        \
                  task->callback(queue, SILC_TASK_READ,                      \
                                 task->context, i);                          \
                   silc_mutex_lock(schedule->lock);                          \
+                  silc_mutex_lock(queue->lock);                                     \
                }                                                            \
              }                                                              \
                                                                             \
              if (task->valid && schedule->fd_list.fd[i] != -1) {            \
                /* Task ready for writing */                                 \
                if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_WRITE))) {   \
+                  silc_mutex_unlock(queue->lock);                           \
                   silc_mutex_unlock(schedule->lock);                        \
                  task->callback(queue, SILC_TASK_WRITE,                     \
                                 task->context, i);                          \
                   silc_mutex_lock(schedule->lock);                          \
+                  silc_mutex_lock(queue->lock);                                     \
                }                                                            \
              }                                                              \
                                                                             \
@@ -559,7 +591,6 @@ do {                                                                             \
          }                                                                  \
        }                                                                    \
       }                                                                             \
-    silc_mutex_unlock(schedule->lock);                                      \
   }                                                                         \
 } while(0)
 
@@ -574,6 +605,9 @@ bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
 
   SILC_LOG_DEBUG(("In scheduler loop"));
 
+  if (!schedule->is_locked)
+    silc_mutex_lock(schedule->lock);
+
   /* If the task queues aren't initialized or we aren't valid anymore
      we will return */
   if ((!schedule->fd_queue && !schedule->timeout_queue 
@@ -588,14 +622,14 @@ bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
   schedule->max_fd = -1;
   is_run = FALSE;
 
-  /* Calculate next timeout for select(). This is the timeout value
+  /* Calculate next timeout for silc_select(). This is the timeout value
      when at earliest some of the timeout tasks expire. */
+  silc_mutex_lock(schedule->timeout_queue->lock);
   SILC_SCHEDULE_SELECT_TIMEOUT;
-
-  silc_mutex_lock(schedule->lock);
+  silc_mutex_unlock(schedule->timeout_queue->lock);
 
   /* Add the file descriptors to the fd sets. These are the non-timeout
-     tasks. The select() listens to these file descriptors. */
+     tasks. The silc_select() listens to these file descriptors. */
   SILC_SCHEDULE_SELECT_TASKS;
 
   if (schedule->max_fd == -1 && !schedule->timeout)
@@ -621,6 +655,8 @@ bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
   ret = silc_select(schedule->max_fd + 1, &schedule->in,
                    &schedule->out, 0, schedule->timeout);
 
+  silc_mutex_lock(schedule->lock);
+
   switch (ret) {
   case -1:
     /* Error */
@@ -631,18 +667,27 @@ bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)
   case 0:
     /* Timeout */
     SILC_LOG_DEBUG(("Running timeout tasks"));
+    silc_mutex_lock(schedule->timeout_queue->lock);
     silc_gettimeofday(&curtime);
     SILC_SCHEDULE_RUN_TIMEOUT_TASKS;
+    silc_mutex_unlock(schedule->timeout_queue->lock);
     break;
   default:
     /* There is some data available now */
     SILC_LOG_DEBUG(("Running non-timeout tasks"));
+    silc_mutex_lock(schedule->fd_queue->lock);
     SILC_SCHEDULE_RUN_TASKS;
+    silc_mutex_unlock(schedule->fd_queue->lock);
 
+    silc_mutex_lock(schedule->generic_queue->lock);
     SILC_SCHEDULE_RUN_GENERIC_TASKS;
+    silc_mutex_unlock(schedule->generic_queue->lock);
     break;
   }
 
+  if (!schedule->is_locked)
+    silc_mutex_unlock(schedule->lock);
+
   return TRUE;
 }
 
@@ -659,9 +704,14 @@ void silc_schedule(SilcSchedule schedule)
     return;
   }
 
+  silc_mutex_lock(schedule->lock);
+  schedule->is_locked = TRUE;
+
   /* Start the scheduler loop */
   while (silc_schedule_one(schedule, -1)) 
     ;
+
+  silc_mutex_unlock(schedule->lock);
 }
 
 /* Wakes up the scheduler. This is used only in multi-threaded
index 9cd68c3ba276532f774b78adb6bef5ef9b4cdcda..7751603f61d68c11bbe62cbaa24253565f77015f 100644 (file)
@@ -58,9 +58,9 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
 
   pthread_attr_destroy(&attr);
 
-  SILC_LOG_DEBUG(("Created thread %p", (SilcThread)ret));
+  SILC_LOG_DEBUG(("Created thread %p", (SilcThread)thread));
 
-  return (SilcThread)ret;
+  return (SilcThread)thread;
 }
 
 void silc_thread_exit(void *exit_value)