[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r3145 - GNUnet/src/server,
grothoff <=