gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3145 - GNUnet/src/server


From: grothoff
Subject: [GNUnet-SVN] r3145 - GNUnet/src/server
Date: Fri, 28 Jul 2006 03:03:00 -0700 (PDT)

Author: grothoff
Date: 2006-07-28 03:02:58 -0700 (Fri, 28 Jul 2006)
New Revision: 3145

Modified:
   GNUnet/src/server/tcpserver.c
   GNUnet/src/server/tcpserver.h
Log:
tcpserver

Modified: GNUnet/src/server/tcpserver.c
===================================================================
--- GNUnet/src/server/tcpserver.c       2006-07-28 09:32:39 UTC (rev 3144)
+++ GNUnet/src/server/tcpserver.c       2006-07-28 10:02:58 UTC (rev 3145)
@@ -22,6 +22,8 @@
  * @file server/tcpserver.c
  * @brief TCP server (gnunetd-client communication using util/tcpio.c).
  * @author Christian Grothoff
+ *
+ * TODO: configuration management (signaling of configuration change)
  */
 
 #include "platform.h"
@@ -45,26 +47,6 @@
 static unsigned int max_registeredType = 0;
 
 /**
- * Mutex to guard access to the handler array.
- */
-static struct MUTEX * handlerlock;
-
-/**
- * Mutex to guard access to the client list.
- */
-static struct MUTEX * clientlock;
-
-/**
- * The thread that waits for new connections.
- */
-static struct PTHREAD * TCPLISTENER_listener_;
-
-/**
- * Pipe to communicate with select thread
- */
-static int signalingPipe[2];
-
-/**
  * Handlers to call if client exits.
  */
 static ClientExitHandler * exitHandlers;
@@ -75,54 +57,29 @@
 static unsigned int exitHandlerCount;
 
 /**
- * Signals for control-thread to server-thread communication
+ * Mutex to guard access to the handler array.
  */
-static struct SEMAPHORE * serverSignal;
+static struct MUTEX * handlerlock;
 
 /**
- * Should the select-thread exit?
+ * The thread that waits for new connections.
  */
-static int tcpserver_keep_running = NO;
+static struct SelectHandle * selector;
 
-
 static struct GE_Context * ectx;
 
+static struct GC_Configuration * cfg;
+
 /**
- * Per-client data structure (kept in linked list).  Also: the opaque
- * handle for client connections passed by the core to the CSHandlers.
+ * Per-client data structure.
  */
-typedef struct ClientH {
-  /**
-   * Socket to communicate with the client.
-   */
+typedef struct ClientHandle {
+
   struct SocketHandle * sock;
 
-  char * readBuffer;
+} ClientHandle;
 
-  unsigned int readBufferPos;
-
-  unsigned int readBufferSize;
-
-  char * writeBuffer;
-
-  unsigned int writeBufferSize;
-
-  MESSAGE_HEADER ** writeQueue;
-
-  unsigned int writeQueueSize;
-
-  ClientHandle next;
-
-} ClientThreadHandle;
-
-
 /**
- * Start of the linked list of client structures.
- */
-static ClientHandle clientList = NULL;
-
-
-/**
  * Configuration...
  */
 static struct CIDRNetwork * trustedNetworks_ = NULL;
@@ -135,24 +92,6 @@
                           ip);
 }
 
-static void signalSelect() {
-  static char i = 0;
-  int ret;
-
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "signaling select.\n");
-#endif
-  ret = WRITE(signalingPipe[1],
-             &i,
-             sizeof(char));
-  if (ret != sizeof(char))
-    if (errno != EAGAIN)
-      GE_LOG_STRERROR(ectx,
-                     GE_ERROR | GE_WARNING | GE_USER,
-                     "write");
-}
-
 int registerClientExitHandler(ClientExitHandler callback) {
   MUTEX_LOCK(handlerlock);
   GROW(exitHandlers,
@@ -163,56 +102,6 @@
   return OK;
 }
 
-/**
- * The client identified by 'session' has disconnected.  Close the
- * socket, free the buffers, unlink session from the linked list.
- */
-void terminateClientConnection(ClientHandle session) {
-  ClientHandle prev;
-  ClientHandle pos;
-  int i;
-
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "Destroying session %p.\n",
-      session);
-#endif
-  /* avoid deadlock: give up the lock while
-     the client is processing; since only (!) the
-     select-thread can possibly free handle/readbuffer,
-     releasing the lock here is safe. */
-  MUTEX_UNLOCK(clientlock);
-  MUTEX_LOCK(handlerlock);
-  for (i=0;i<exitHandlerCount;i++)
-    exitHandlers[i](session);
-  MUTEX_UNLOCK(handlerlock);
-  MUTEX_LOCK(clientlock);
-  prev = NULL;
-  pos = clientList;
-  while (pos != session) {
-    GE_ASSERT(ectx, pos != NULL);
-    prev = pos;
-    pos = pos->next;
-  }
-  if (prev == NULL)
-    clientList = session->next;
-  else
-    prev->next = session->next;
-  socket_destroy(session->sock);
-  GROW(session->writeBuffer,
-       session->writeBufferSize,
-       0);
-  GROW(session->readBuffer,
-       session->readBufferSize,
-       0);
-  for (i=session->writeQueueSize-1;i>=0;i--)
-    FREE(session->writeQueue[i]);
-  GROW(session->writeQueue,
-       session->writeQueueSize,
-       0);
-  FREE(session);
-}
-
 int unregisterClientExitHandler(ClientExitHandler callback) {
   int i;
 
@@ -231,52 +120,70 @@
   return SYSERR;
 }
 
+static void * select_accept_handler(void * ah_cls,
+                                   struct SelectHandle * sh,
+                                   struct SocketHandle * sock,
+                                   const void * addr,
+                                   unsigned int addr_len) {
+  struct ClientHandle * session;
+  IPaddr ip;
+
+  if (addr_len != sizeof(IPaddr))
+    return NULL;
+  memcpy(&ip,
+        addr,
+        addr_len);
+  if (! isWhitelisted(ip))
+    return NULL;
+  session = MALLOC(sizeof(ClientHandle));
+  session->sock = sock;
+  return session;
+}
+
+static void select_close_handler(void * ch_cls,
+                                struct SelectHandle * sh,
+                                struct SocketHandle * sock,
+                                void * sock_ctx) {
+  ClientHandle * session = sock_ctx;
+  int i;
+
+  MUTEX_LOCK(handlerlock);
+  for (i=0;i<exitHandlerCount;i++)
+    exitHandlers[i](session);
+  MUTEX_UNLOCK(handlerlock);
+  FREE(session);
+}
+
 /**
  * Send a message to the client identified by the handle.  Note that
  * the core will typically buffer these messages as much as possible
- * and only return SYSERR if it runs out of buffers.  Returning OK
+ * and only return errors if it runs out of buffers.  Returning OK
  * on the other hand does NOT confirm delivery since the actual
  * transfer happens asynchronously.
  */
-int sendToClient(ClientHandle handle,
+int sendToClient(struct ClientHandle * handle,
                 const MESSAGE_HEADER * message) {
-  MESSAGE_HEADER * cpy;
+  return select_write(selector,
+                     handle->sock,
+                     message,
+                     NO,
+                     YES);
+}
 
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "Sending message to client %p.\n",
-      handle);
-#endif
-  cpy = MALLOC(ntohs(message->size));
-  memcpy(cpy, 
-        message, 
-        ntohs(message->size));
-  MUTEX_LOCK(clientlock);
-  GROW(handle->writeQueue,
-       handle->writeQueueSize,
-       handle->writeQueueSize+1);
-  handle->writeQueue[handle->writeQueueSize-1] = cpy;
-  MUTEX_UNLOCK(clientlock);
-  signalSelect();
-  return OK;
+void terminateClientConnection(struct ClientHandle * sock) {
+  select_disconnect(selector,
+                   sock->sock);
 }
 
-/**
- * Handle a message (that was decrypted if needed).
- * Checks the CRC and if that's ok, processes the
- * message by calling the registered handler for
- * each message part.
- */
-static int processHelper(MESSAGE_HEADER * msg,
-                        ClientHandle sender) {
+static int select_message_handler(void * mh_cls,
+                                 struct SelectHandle * sh,
+                                 struct SocketHandle * sock,
+                                 void * sock_ctx,
+                                 const MESSAGE_HEADER * msg) {
+  struct ClientHandle * sender = sock_ctx;
   unsigned short ptyp;
   CSHandler callback;
 
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "Processing message from %p.\n",
-      sender);
-#endif
   ptyp = htons(msg->type);
   MUTEX_LOCK(handlerlock);
   if (ptyp >= max_registeredType) {
@@ -310,109 +217,86 @@
 }
 
 /**
- * Handle data available on the TCP socket descriptor. This method
- * first aquires a slot to register this socket for the writeBack
- * method (@see writeBack) and then demultiplexes all TCP traffic
- * received to the appropriate handlers.
- * @param sockDescriptor the socket that we are listening to (fresh)
+ * Get the GNUnet UDP port from the configuration,
+ * or from /etc/services if it is not specified in
+ * the config file.
  */
-static int readAndProcess(ClientHandle handle) {
-  unsigned int len;
-  int ret;
-  size_t size;
+static unsigned short getGNUnetPort() {
+  struct servent * pse;        /* pointer to service information entry */
+  unsigned long long port;
 
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "Reading from client %p.\n",
-      handle);
-#endif
-  ret = socket_recv(handle->sock,
-                   NC_Blocking | NC_IgnoreInt,
-                   &handle->readBuffer[handle->readBufferPos],
-                   handle->readBufferSize - handle->readBufferPos,
-                   &size);
-  if ( (ret == SYSERR) || (size == 0) ) {
-#if DEBUG_TCPHANDLER
-    LOG(LOG_DEBUG,
-       "Read 0 bytes from client %p. Closing.\n",
-       handle);
-#endif
-    return SYSERR; /* other side closed connection */
+  if (-1 == GC_get_configuration_value_number(cfg,
+                                             "TCP",
+                                             "PORT",
+                                             1,
+                                             65535,
+                                             2086,
+                                             &port)) {
+    if ((pse = getservbyname("gnunet", "tcp")))
+      port = htons(pse->s_port);
+    else
+      port = 0;
   }
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "Read %u bytes from client %p.\n",
-      size,
-      handle);
-#endif
-  handle->readBufferPos += size;
-  ret = OK;
-  while (ret == OK) {
-    if (handle->readBufferPos < sizeof(MESSAGE_HEADER))
-      return OK;
-    len = ntohs(((MESSAGE_HEADER*)handle->readBuffer)->size);
-#if DEBUG_TCPHANDLER
-    GE_LOG(ectx,
-          GE_DEBUG | GE_USER | GE_BULK,
-          "Total size is %u bytes, have %u.\n",
-          len,
-          handle->readBufferPos);
-#endif
-    if (len > handle->readBufferSize) /* if MTU larger than expected, grow! */
-      GROW(handle->readBuffer,
-          handle->readBufferSize,
-          len);
-    if (handle->readBufferPos < len)
-      return OK;
-    /* avoid deadlock: give up the lock while
-       the client is processing; since only (!) the
-       select-thread can possibly free handle/readbuffer,
-     releasing the lock here is safe. */
-    MUTEX_UNLOCK(clientlock);
-    ret = processHelper((MESSAGE_HEADER*)handle->readBuffer,
-                     handle);
-    MUTEX_LOCK(clientlock);
-    /* finally, shrink buffer adequately */
-    memmove(&handle->readBuffer[0],
-           &handle->readBuffer[len],
-           handle->readBufferPos - len);
-    handle->readBufferPos -= len;
-  }
-  return ret;
+  return (unsigned short) port;
 }
 
 /**
- * Initialize the TCP port and listen for incoming connections.
+ * Initialize the TCP port and listen for incoming client connections.
  */
-static void * tcpListenMain(void * unused) {
-  int max;
-  int ret;
+int initTCPServer(struct GE_Context * e,
+                 struct GC_Configuration * c) {
   int listenerFD;
-  socklen_t lenOfIncomingAddr;
   int listenerPort;
-  struct sockaddr_in serverAddr, clientAddr;
+  struct sockaddr_in serverAddr;
   const int on = 1;
-  ClientHandle pos;
-  struct stat buf;
-  fd_set readSet;
-  fd_set errorSet;
-  fd_set writeSet;
-  int success;
+  char * ch;
 
-  /* TODO: move bind code into init! */
+  cfg = c;
+  ectx = e;
+#if 0
+  if (testConfigurationString("TCPSERVER",
+                             "DISABLE",
+                             "YES"))
+    return OK;
+#endif
+
+  /* move to reload-configuration method! */
+  ch = NULL;
+  if (-1 == GC_get_configuration_value_string(cfg,
+                                             "NETWORK",
+                                             "TRUSTED",
+                                             "127.0.0.0/8;",
+                                             &ch)) 
+    return SYSERR;
+  GE_ASSERT(ectx, ch != NULL);
+  trustedNetworks_ = parse_ipv4_network_specification(ectx,
+                                                     ch);
+  if (trustedNetworks_ == NULL) {
+    GE_LOG(ectx,
+          GE_FATAL | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+          _("Malformed network specification in the configuration in section 
`%s' for entry `%s': %s\n"),
+          "NETWORK",
+          "TRUSTED",
+          ch);    
+    FREE(ch);
+    return SYSERR;
+  }
+  FREE(ch);
+
   listenerPort = getGNUnetPort();
-  /* create the socket */
-  while ( (listenerFD = SOCKET(PF_INET,
-                              SOCK_STREAM,
-                              0)) < 0) {
-    GE_DIE_STRERROR(ectx,
+  if (listenerPort == 0)
+    return SYSERR;
+  listenerFD = SOCKET(PF_INET,
+                     SOCK_STREAM,
+                     0);
+  if (listenerFD < 0) {
+    GE_LOG_STRERROR(ectx,
                    GE_FATAL | GE_ADMIN | GE_USER | GE_IMMEDIATE,
                    "socket");
-    sleep(30);
+    return SYSERR;
   }
-
   /* fill in the inet address structure */
-  memset((char *) &serverAddr,
+  memset(&serverAddr,
         0,
         sizeof(serverAddr));
   serverAddr.sin_family
@@ -421,15 +305,14 @@
     = htonl(INADDR_ANY);
   serverAddr.sin_port
     = htons(listenerPort);
-
   if ( SETSOCKOPT(listenerFD,
                  SOL_SOCKET,
                  SO_REUSEADDR,
-                 &on, sizeof(on)) < 0 )
+                 &on,
+                 sizeof(on)) < 0 )
     GE_LOG_STRERROR(ectx,
                    GE_ERROR | GE_ADMIN | GE_BULK, 
                    "setsockopt");
-
   /* bind the socket */
   if (BIND(listenerFD,
           (struct sockaddr *) &serverAddr,
@@ -442,400 +325,49 @@
           _("`%s' failed for port %d. Is gnunetd already running?\n"),
           "bind",
           listenerPort);
-    SEMAPHORE_UP(serverSignal);
-    tcpserver_keep_running = SYSERR;
-    SEMAPHORE_UP(serverSignal);
-    return NULL;
+    return SYSERR;
   }
-
-  /* start listening for new connections */
-  LISTEN(listenerFD, 5); /* max: 5 pending, unhandled connections */
-  SEMAPHORE_UP(serverSignal);
-
-  MUTEX_LOCK(clientlock);
-  /* process incoming data */
-  while (tcpserver_keep_running == YES) {
-    FD_ZERO(&readSet);
-    FD_ZERO(&errorSet);
-    FD_ZERO(&writeSet);
-    if (-1 != FSTAT(listenerFD, &buf)) {
-      FD_SET(listenerFD, &readSet);
-    } else {
-      GE_DIE_STRERROR(ectx,
-                     GE_FATAL,
-                     "fstat");
-    }
-    if (-1 != FSTAT(signalingPipe[0], &buf)) {
-      FD_SET(signalingPipe[0], &readSet);
-    } else {
-      GE_DIE_STRERROR(ectx,
-                     GE_FATAL,
-                     "fstat");
-    }
-    max = signalingPipe[0];
-    if (listenerFD > max)
-      max = listenerFD;
-    pos = clientList;
-    while (pos != NULL) {
-      struct SocketHandle * sock = pos->sock;
-      if (YES == socket_test_valid(sock)) {
-       socket_add_to_select_set(sock, &errorSet, &max);
-       if ( (pos->writeBufferSize > 0) ||
-            (pos->writeQueueSize > 0) )
-         socket_add_to_select_set(sock, &writeSet, &max); /* we have a pending 
write request? */
-       else
-         socket_add_to_select_set(sock, &readSet, &max); /* ONLY read if no 
writes are pending! */
-      } else {
-       ClientHandle ch;
-
-       ch = pos->next;
-       terminateClientConnection(pos);
-       pos = ch;
-       continue;
-      }
-      pos = pos->next;
-    }
-    MUTEX_UNLOCK(clientlock);
-    ret = SELECT(max+1,
-                &readSet,
-                &writeSet,
-                &errorSet,
-                NULL);
-    MUTEX_LOCK(clientlock);
-    if ( (ret == -1) &&
-        ( (errno == EAGAIN) || (errno == EINTR) ) )
-      continue;
-    if (ret == -1) {
-      if (errno == EBADF) {
-       GE_LOG_STRERROR(ectx,
-                       GE_ERROR | GE_DEVELOPER | GE_BULK,
-                       "select");
-      } else {
-       GE_DIE_STRERROR(ectx,
-                       GE_FATAL | GE_ADMIN | GE_IMMEDIATE,
-                       "select");
-      }
-    }
-    if (FD_ISSET(listenerFD, &readSet)) {
-      int sock;
-
-      lenOfIncomingAddr = sizeof(clientAddr);
-      sock = ACCEPT(listenerFD,
-                   (struct sockaddr *)&clientAddr,
-                   &lenOfIncomingAddr);
-      if (sock != -1) {        
-       /* verify clientAddr for eligibility here (ipcheck-style,
-          user should be able to specify who is allowed to connect,
-          otherwise we just close and reject the communication! */
-
-       IPaddr ipaddr;
-
-#if 0
-       printConnectionBuffer();
-#endif
-       GE_ASSERT(ectx, sizeof(struct in_addr) == sizeof(IPaddr));
-       memcpy(&ipaddr,
-              &clientAddr.sin_addr,
-              sizeof(struct in_addr));
-
-       if (NO == isWhitelisted(ipaddr)) {
-         GE_LOG(ectx,
-                GE_WARNING | GE_USER | GE_ADMIN | GE_BULK,
-                _("Rejected unauthorized connection from %u.%u.%u.%u.\n"),
-                PRIP(ntohl(*(int*)&clientAddr.sin_addr)));
-         if (0 != CLOSE(sock))
-           GE_LOG_STRERROR(ectx,
-                           GE_WARNING | GE_ADMIN | GE_BULK,
-                           "close");
-       } else {
-         ClientHandle ch
-           = MALLOC(sizeof(ClientThreadHandle));
-#if DEBUG_TCPHANDLER
-         GE_LOG(ectx,
-                GE_DEBUG | GE_USER | GE_REQUEST,
-                "Accepting connection from %u.%u.%u.%u (socket: %d).\n",
-                PRIP(ntohl(*(int*)&clientAddr.sin_addr)),
-                sock);
-#endif
-         ch->sock = socket_create(ectx,
-                                  NULL,
-                                  sock);
-         ch->readBufferSize = 2048;
-         ch->readBuffer = MALLOC(ch->readBufferSize);
-         ch->readBufferPos = 0;
-         ch->writeBuffer = NULL;
-         ch->writeBufferSize = 0;
-         ch->writeQueue = NULL;
-         ch->writeQueueSize = 0;
-         ch->next = clientList;
-         clientList = ch;
-       }
-      } else {
-       GE_LOG_STRERROR(ectx,
-                       GE_INFO | GE_BULK | GE_ADMIN, "accept");
-      }
-    }
-
-    if (socket_test_select_set(signalingPipe[0], 
-                              &readSet)) {
-      /* allow reading multiple signals in one go in case we get many
-        in one shot... */
-
-#define MAXSIG_BUF 128
-      char buf[MAXSIG_BUF];
-
-#if DEBUG_TCPHANDLER
-      LOG(LOG_DEBUG,
-         "tcpserver eats signal.\n");
-#endif
-      /* just a signal to refresh sets, eat and continue */
-      if (0 >= READ(signalingPipe[0],
-                   &buf[0],
-                   MAXSIG_BUF))
-       GE_LOG_STRERROR(ectx,
-                       GE_WARNING, 
-                       "read");
-    }
-
-    pos = clientList;
-    while (pos != NULL) {
-      struct SocketHandle * sock = pos->sock;
-      if (socket_test_select_set(sock,
-                                &readSet)) {
-#if DEBUG_TCPHANDLER
-       GE_LOG(ectx,
-              GE_DEBUG,
-              "tcpserver reads from %p (socket %d)\n",
-              pos,
-              sock);
-#endif
-       if (SYSERR == readAndProcess(pos)) {
-         ClientHandle ch
-           = pos->next;
-         terminateClientConnection(pos);
-         pos = ch;
-         continue;
-       }
-      }
-      if (socket_test_select_set(sock, &writeSet)) {
-       size_t ret;
-       
-#if DEBUG_TCPHANDLER
-       GE_LOG(ectx,
-              GE_DEBUG,
-              "tcpserver writes to %p.\n",
-              pos);
-#endif
-       if (pos->writeBufferSize == 0) {
-         if (pos->writeQueueSize > 0) {
-           unsigned int len;
-           len = ntohs(pos->writeQueue[0]->size);
-           pos->writeBuffer = (char*)pos->writeQueue[0];
-           pos->writeBufferSize = len;
-           for (len=0;len<pos->writeQueueSize-1;len++)
-             pos->writeQueue[len] = pos->writeQueue[len+1];
-           GROW(pos->writeQueue,
-                pos->writeQueueSize,
-                pos->writeQueueSize-1);
-         } else {
-           GE_BREAK(ectx, 0); /* entry in write set but no messages pending! */
-         }
-       }
-try_again:
-       success = socket_send(sock,
-                             NC_Blocking | NC_IgnoreInt,
-                             pos->writeBuffer,
-                             pos->writeBufferSize,
-                             &ret);
-       if (success == SYSERR) {
-         ClientHandle ch
-           = pos->next;
-         GE_LOG_STRERROR(ectx,
-                         GE_INFO | GE_BULK | GE_USER,
-                         "send");
-         terminateClientConnection(pos);
-         pos = ch;
-         continue;
-       } else if (success == NO) {
-         /* this should only happen under Win9x because
-            of a bug in the socket implementation (KB177346).
-            Let's sleep and try again. */
-         PTHREAD_SLEEP(20 * cronMILLIS);
-         goto try_again;
-       }
-       if (ret == 0) {
-         ClientHandle ch
-           = pos->next;
-          /* send only returns 0 on error (other side closed connection),
-            so close the session */
-         terminateClientConnection(pos);
-         pos = ch;
-         continue;
-       }
-       if (ret == pos->writeBufferSize) {
-         FREENONNULL(pos->writeBuffer);
-         pos->writeBuffer = NULL;
-         pos->writeBufferSize = 0;
-       } else {
-         memmove(pos->writeBuffer,
-                 &pos->writeBuffer[ret],
-                 pos->writeBufferSize - ret);
-         pos->writeBufferSize -= ret;
-       }
-      }
-
-      if (socket_test_select_set(sock,
-                                &errorSet)) {
-#if DEBUG_TCPHANDLER
-       GE_LOG(ectx,
-              GE_DEBUG,
-              "tcpserver error on connection %p.\n",
-              pos);
-#endif
-       ClientHandle ch
-         = pos->next;
-       terminateClientConnection(pos);
-       pos = ch;
-       continue;
-      }
-      pos = pos->next;
-    }
-  } /* while tcpserver_keep_running */
-
-  /* shutdown... */
-  if (0 != CLOSE(listenerFD))
-    GE_LOG_STRERROR(ectx,
-                   GE_ERROR,
-                   "close");
-
-  /* close all sessions */
-  while (clientList != NULL)
-    terminateClientConnection(clientList);
-
-  MUTEX_UNLOCK(clientlock);
-  SEMAPHORE_UP(serverSignal);  /* signal shutdown */
-  return NULL;
+  handlerlock = MUTEX_CREATE(YES);
+  selector = select_create(e,
+                          NULL,
+                          listenerFD,
+                          sizeof(IPaddr),
+                          0, /* no timeout */
+                          &select_message_handler,
+                          NULL,
+                          &select_accept_handler,
+                          NULL,
+                          &select_close_handler,
+                          NULL,
+                          0 /* no memory quota */);
+  if (selector == NULL) 
+    return SYSERR;  
+  return OK;
 }
 
-
 /**
- * Initialize the TCP port and listen for incoming client connections.
+ * Shutdown the module.
  */
-int initTCPServer(struct GE_Context * e,
-                 struct GC_Configuration * cfg) {
-  char * ch;
-
-  ectx = e;
-  if (tcpserver_keep_running == YES) {
-    GE_BREAK(ectx, 0);
-    return SYSERR;
-  }
-  ch = NULL;
-  if (-1 == GC_get_configuration_value_string(cfg,
-                                             "NETWORK",
-                                             "TRUSTED",
-                                             "127.0.0.0/8;",
-                                             &ch)) 
-    return SYSERR;
-  GE_ASSERT(ectx, ch != NULL);
-  trustedNetworks_ = parse_ipv4_network_specification(ectx,
-                                                     ch);
-  if (trustedNetworks_ == NULL) {
-    GE_LOG(ectx,
-          GE_FATAL | GE_USER | GE_ADMIN | GE_IMMEDIATE,
-          _("Malformed network specification in the configuration in section 
`%s' for entry `%s': %s\n"),
-          "NETWORK",
-          "TRUSTED",
-          ch);    
-    FREE(ch);
-    return SYSERR;
-  }
-  FREE(ch);
-
-  PIPE(signalingPipe);
-  /* important: make signalingPipe non-blocking
-     to avoid stalling on signaling! */
-  setBlocking(signalingPipe[1], NO);
-
-  handlerlock = MUTEX_CREATE(YES);
-  clientlock = MUTEX_CREATE(YES);
+int stopTCPServer() {
 #if 0
   if (testConfigurationString("TCPSERVER",
                              "DISABLE",
                              "YES"))
     return OK;
 #endif
-  tcpserver_keep_running = YES;
-  serverSignal = SEMAPHORE_CREATE(0);
-  TCPLISTENER_listener_ = PTHREAD_CREATE(&tcpListenMain,
-                                        NULL,
-                                        64*1024);
-  if (TCPLISTENER_listener_ == NULL) {
-    GE_LOG_STRERROR(ectx,
-                   GE_ERROR,
-                   "pthread_create");
-    SEMAPHORE_DESTROY(serverSignal);
-    serverSignal = NULL;
-    tcpserver_keep_running = NO;
-    MUTEX_DESTROY(handlerlock);
-    handlerlock = NULL;
-    MUTEX_DESTROY(clientlock);
-    clientlock = NULL;
-    return SYSERR;
-  }
-  SEMAPHORE_DOWN(serverSignal, YES);
+  GE_ASSERT(ectx, selector != NULL);
+  select_destroy(selector);
   return OK;
 }
 
-/**
- * Shutdown the module.
- */
-int stopTCPServer() {
-  void * unused;
-
-  if ( ( tcpserver_keep_running == YES) &&
-       ( serverSignal != NULL) ) {
-#if DEBUG_TCPHANDLER
-    LOG(LOG_DEBUG,
-       "stopping TCP server\n");
-#endif
-    /* stop server thread */
-    tcpserver_keep_running = NO;
-    signalSelect();
-    SEMAPHORE_DOWN(serverSignal, YES);
-    SEMAPHORE_DESTROY(serverSignal);
-    serverSignal = NULL;
-    PTHREAD_JOIN(TCPLISTENER_listener_,
-                &unused);
-    TCPLISTENER_listener_ = NULL;
-    return OK;
-  } else {
-#if 0
-    if (testConfigurationString("TCPSERVER",
-                               "DISABLE",
-                               "YES"))
-      return OK;
-#endif
-    return SYSERR;
-  }
-}
-
 int doneTCPServer() {
-  stopTCPServer(); /* just to be sure; used mostly
-                     for the benefit of gnunet-update
-                     and other gnunet-tools that are
-                     not gnunetd */
-#if DEBUG_TCPHANDLER
-  LOG(LOG_DEBUG,
-      "entering %s\n", __FUNCTION__);
-#endif
-  CLOSE(signalingPipe[0]);
-  CLOSE(signalingPipe[1]);
-  /* free data structures */
+  if (selector != NULL)
+    stopTCPServer(); /* just to be sure; used mostly
+                       for the benefit of gnunet-update
+                       and other gnunet-tools that are
+                       not gnunetd */
   MUTEX_DESTROY(handlerlock);
   handlerlock = NULL;
-  MUTEX_DESTROY(clientlock);
-  clientlock = NULL;
   GROW(handlers,
        max_registeredType,
        0);
@@ -917,12 +449,12 @@
  * @return SYSERR on error, OK if the return value was
  *         send successfully
  */
-int sendTCPResultToClient(ClientHandle sock,
+int sendTCPResultToClient(struct ClientHandle * sock,
                          int ret) {
-  CS_returnvalue_MESSAGE rv;
+  RETURN_VALUE_MESSAGE rv;
 
   rv.header.size
-    = htons(sizeof(CS_returnvalue_MESSAGE));
+    = htons(sizeof(RETURN_VALUE_MESSAGE));
   rv.header.type
     = htons(CS_PROTO_RETURN_VALUE);
   rv.return_value

Modified: GNUnet/src/server/tcpserver.h
===================================================================
--- GNUnet/src/server/tcpserver.h       2006-07-28 09:32:39 UTC (rev 3144)
+++ GNUnet/src/server/tcpserver.h       2006-07-28 10:02:58 UTC (rev 3145)
@@ -86,7 +86,7 @@
  * on the other hand does NOT confirm delivery since the actual
  * transfer happens asynchronously.
  */
-int sendToClient(ClientHandle handle,
+int sendToClient(struct ClientHandle * handle,
                 const MESSAGE_HEADER * message);
 
 
@@ -98,11 +98,11 @@
  * @return SYSERR on error, OK if the return value was
  *         send successfully
  */
-int sendTCPResultToClient(ClientHandle sock,
+int sendTCPResultToClient(struct ClientHandle * sock,
                          int ret);
 
 
-void terminateClientConnection(ClientHandle sock);
+void terminateClientConnection(struct ClientHandle * sock);
 
 /**
  * Check if a handler is registered for a given





reply via email to

[Prev in Thread] Current Thread [Next in Thread]