Author: grothoff Date: 2006-07-25 02:50:37 -0700 (Tue, 25 Jul 2006) New Revision: 3134
Modified: GNUnet/src/include/gnunet_util_network.h GNUnet/src/transports/nat.c GNUnet/src/transports/tcp.c GNUnet/src/transports/udp.c GNUnet/src/util/network/io.c GNUnet/todo Log: fixing udp and nat Modified: GNUnet/src/include/gnunet_util_network.h =================================================================== --- GNUnet/src/include/gnunet_util_network.h 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/src/include/gnunet_util_network.h 2006-07-25 09:50:37 UTC (rev 3134) @@ -36,6 +36,7 @@ #include "gnunet_util_string.h" #include "gnunet_util_os.h" #include "gnunet_util_threads.h" +#include <sys/socket.h> #ifdef __cplusplus extern "C" { @@ -452,6 +453,14 @@ size_t max, size_t * read); +int socket_recv_from(struct SocketHandle * s, + NC_KIND nc, + void * buf, + size_t max, + size_t * read, + struct sockaddr * from, + socklen_t * fromlen); + /** * Do a write on the given socket. * Write at most max bytes from buf. @@ -469,6 +478,14 @@ size_t max, size_t * sent); +int socket_send_to(struct SocketHandle * s, + NC_KIND nc, + const void * buf, + size_t max, + size_t * sent, + const struct sockaddr * dst, + socklen_t dstlen); + /** * Check if socket is valid * @return YES if valid, NO otherwise Modified: GNUnet/src/transports/nat.c =================================================================== --- GNUnet/src/transports/nat.c 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/src/transports/nat.c 2006-07-25 09:50:37 UTC (rev 3134) @@ -43,9 +43,10 @@ /* apis (our advertised API and the core api ) */ static TransportAPI natAPI; -static CoreAPIForTransport * coreAPI = NULL; +static CoreAPIForTransport * coreAPI; + /* *************** API implementation *************** */ /** @@ -57,15 +58,20 @@ * @return OK on success, SYSERR on failure */ static int verifyHelo(const P2P_hello_MESSAGE * helo) { - + const char * yesno[] = { "YES", "NO", NULL }; + const char * value; if ( (ntohs(helo->senderAddressSize) != sizeof(HostAddress)) || (ntohs(helo->header.size) != P2P_hello_MESSAGE_size(helo)) || (ntohs(helo->header.type) != p2p_PROTO_hello) ) { return SYSERR; /* obviously invalid */ } else { - if (testConfigurationString("NAT", - "LIMITED", - "YES")) { + if ( (-1 != GC_get_configuration_value_choice(coreAPI->cfg, + "NAT", + "LIMITED", + yesno, + "NO", + &value)) && + (value == "YES") ) { /* if WE are a NAT and this is not our hello, it is invalid since NAT-to-NAT is not possible! */ if (equalsHashCode512(&coreAPI->myIdentity->hashPubKey, @@ -86,11 +92,17 @@ * @return hello on success, NULL on error */ static P2P_hello_MESSAGE * createhello() { + const char * yesno[] = { "YES", "NO", NULL }; + const char * value; P2P_hello_MESSAGE * msg; - if (! testConfigurationString("NAT", - "LIMITED", - "YES")) + if (! ( (-1 != GC_get_configuration_value_choice(coreAPI->cfg, + "NAT", + "LIMITED", + yesno, + "NO", + &value)) && + (value == "YES") ) ) return NULL; msg = MALLOC(sizeof(P2P_hello_MESSAGE) + sizeof(HostAddress)); Modified: GNUnet/src/transports/tcp.c =================================================================== --- GNUnet/src/transports/tcp.c 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/src/transports/tcp.c 2006-07-25 09:50:37 UTC (rev 3134) @@ -1482,7 +1482,7 @@ * Reload the configuration. Should never fail (keep old * configuration on error, syslog errors!) */ -static void reloadConfiguration(void) { +static void reloadConfiguration() { char * ch; MUTEX_LOCK(tcplock); Modified: GNUnet/src/transports/udp.c =================================================================== --- GNUnet/src/transports/udp.c 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/src/transports/udp.c 2006-07-25 09:50:37 UTC (rev 3134) @@ -28,8 +28,8 @@ #include "gnunet_protocols.h" #include "gnunet_transport.h" #include "gnunet_stats_service.h" +#include "ip.h" #include "platform.h" -#include "ip.h" #define DEBUG_UDP NO @@ -84,6 +84,7 @@ /* apis (our advertised API and the core api ) */ static CoreAPIForTransport * coreAPI; + static TransportAPI udpAPI; static Stats_ServiceAPI * stats; @@ -94,30 +95,37 @@ static int stat_bytesDropped; +static struct GE_Context * ectx; +static struct GC_Configuration * cfg; + +static struct LoadMonitor * load_monitor; + /** * thread that listens for inbound messages */ -static PTHREAD_T dispatchThread; +static struct PTHREAD * dispatchThread; /** * the socket that we receive all data from */ -static int udp_sock = -1; +static struct SocketHandle * udp_sock; /** * Semaphore for communication with the * udp server thread. */ -static Semaphore * serverSignal; +static struct SEMAPHORE * serverSignal; + static int udp_shutdown = YES; /** * configuration */ -static struct CIDRNetwork * filteredNetworks_ = NULL; -static Mutex configLock; +static struct CIDRNetwork * filteredNetworks_; +static struct MUTEX * configLock; + /** * Keep used port locally, the one in the configuration * may change and then we would not be able to send @@ -134,54 +142,70 @@ */ static unsigned short getGNUnetUDPPort() { struct servent * pse; /* pointer to service information entry */ - unsigned short port; - - port = (unsigned short) getConfigurationInt("UDP", - "PORT"); - if (port == 0) { /* try lookup in services */ + unsigned long long port; + + if (-1 == GC_get_configuration_value_number(cfg, + "TCP", + "PORT", + 1, + 65535, + 2086, + &port)) { if ((pse = getservbyname("gnunet", "udp"))) - port = ntohs(pse->s_port); + port = htons(pse->s_port); else - errexit(_("Cannot determine port to bind to. " - " Define in configuration file in section `%s' under `%s' " - "or in `%s' under %s/%s.\n"), - "UDP", - "PORT", - "/etc/services", - "udp", - "gnunet"); + port = 0; } - return port; + return (unsigned short) port; } /** * Allocate and bind a server socket for the UDP transport. */ -static int passivesock(unsigned short port) { +static struct SocketHandle * passivesock(unsigned short port) { struct sockaddr_in sin; int sock; const int on = 1; sock = SOCKET(PF_INET, SOCK_DGRAM, UDP_PROTOCOL_NUMBER); if (sock < 0) - DIE_STRERROR("socket"); - if ( SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0 ) - DIE_STRERROR("setsockopt"); + GE_DIE_STRERROR(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + "socket"); + if ( SETSOCKOPT(sock, + SOL_SOCKET, + SO_REUSEADDR, + &on, + sizeof(on)) < 0 ) + GE_DIE_STRERROR(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + "setsockopt"); if (port != 0) { - memset(&sin, 0, sizeof(sin)); + memset(&sin, + 0, + sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); if (BIND(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - LOG_STRERROR(LOG_FATAL, "bind"); - errexit(_("Failed to bind to UDP port %d.\n"), - port); + GE_LOG_STRERROR(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + "bind"); + GE_LOG(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + _("Failed to bind to UDP port %d.\n"), + port); + GE_DIE_STRERROR(ectx, + GE_FATAL | GE_USER | GE_IMMEDIATE, + "bind"); } } /* do not bind if port == 0, then we use send-only! */ - return sock; + return socket_create(ectx, + load_monitor, + sock); } /** @@ -190,10 +214,10 @@ static int isBlacklisted(IPaddr ip) { int ret; - MUTEX_LOCK(&configLock); - ret = checkIPListed(filteredNetworks_, - ip); - MUTEX_UNLOCK(&configLock); + MUTEX_LOCK(configLock); + ret = check_ipv4_listed(filteredNetworks_, + ip); + MUTEX_UNLOCK(configLock); return ret; } @@ -201,11 +225,10 @@ * Listen on the given socket and distribute the packets to the UDP * handler. */ -static void * listenAndDistribute() { +static void * listenAndDistribute(void * unused) { struct sockaddr_in incoming; socklen_t addrlen = sizeof(incoming); - int size; - EncName enc; + size_t size; P2P_PACKET * mp; UDPMessage udpm; IPaddr ipaddr; @@ -215,57 +238,72 @@ fd_set readSet; fd_set errorSet; fd_set writeSet; + int max; +#if DEBUG_UDP + EncName enc; +#endif SEMAPHORE_UP(serverSignal); while (udp_shutdown == NO) { FD_ZERO(&readSet); FD_ZERO(&writeSet); FD_ZERO(&errorSet); - FD_SET(udp_sock, &readSet); - ret = SELECT(udp_sock + 1, &readSet, &writeSet, &errorSet, NULL); + max = 0; + socket_add_to_select_set(udp_sock, &readSet, &max); + ret = SELECT(max + 1, + &readSet, + &writeSet, + &errorSet, + NULL); if (ret == -1) { if (udp_shutdown == YES) break; if (errno == EINTR) continue; - DIE_STRERROR("select"); + GE_DIE_STRERROR(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + "select"); } - if (! FD_ISSET(udp_sock, &readSet)) + if (! socket_test_select_set(udp_sock, &readSet)) continue; pending = 0; /* @todo FIXME in PlibC */ #ifdef MINGW - error = ioctlsocket(udp_sock, + error = ioctlsocket(socket_get_os_socket(udp_sock), + FIONREAD, + &pending); #else - error = ioctl(udp_sock, -#endif + error = ioctl(socket_get_os_socket(udp_sock), FIONREAD, &pending); +#endif if (error != 0) { - LOG_STRERROR(LOG_ERROR, "ioctl"); + GE_LOG_STRERROR(ectx, + GE_ERROR | GE_ADMIN | GE_BULK, + "ioctl"); continue; } if (pending <= 0) { - LOG(LOG_WARNING, - _("UDP: select returned, but ioctl reports %d bytes available!\n"), - pending); + GE_LOG(ectx, + GE_WARNING | GE_ADMIN | GE_BULK, + _("UDP: select returned, but ioctl reports %d bytes available!\n"), + pending); if (pending == 0) { /* maybe empty UDP packet was sent (see report on bug-gnunet, 5/11/6; read 0 bytes from UDP just to kill potential empty packet! */ memset(&incoming, 0, sizeof(struct sockaddr_in)); - RECVFROM(udp_sock, - NULL, - 0, - 0, - (struct sockaddr * )&incoming, - &addrlen); + socket_recv(udp_sock, + NC_Nonblocking, + NULL, + 0, + &size); } continue; } if (pending >= 65536) { - BREAK(); + GE_BREAK(ectx, 0); continue; } mp = MALLOC(sizeof(P2P_PACKET)); @@ -278,14 +316,14 @@ FREE(mp); break; } - size = RECVFROM(udp_sock, - mp->msg, - pending, - 0, - (struct sockaddr * )&incoming, - &addrlen); - if ( (size < 0) || - (udp_shutdown == YES) ) { + if (YES != socket_recv_from(udp_sock, + NC_Blocking, + mp->msg, + pending, + &size, + (struct sockaddr * )&incoming, + &addrlen) || + (udp_shutdown == YES) ) { FREE(mp->msg); FREE(mp); if (udp_shutdown == NO) { @@ -294,19 +332,17 @@ (errno == ECONNREFUSED) ) continue; } - if (udp_shutdown == NO) - LOG_STRERROR(LOG_ERROR, "recvfrom"); break; /* die/shutdown */ } - incrementBytesReceived(size); stats->change(stat_bytesReceived, size); if ((unsigned int)size <= sizeof(UDPMessage)) { - LOG(LOG_INFO, - _("Received invalid UDP message from %u.%u.%u.%u:%u, dropping.\n"), - PRIP(ntohl(*(int*)&incoming.sin_addr)), - ntohs(incoming.sin_port)); + GE_LOG(ectx, + GE_INFO | GE_BULK | GE_USER, + _("Received invalid UDP message from %u.%u.%u.%u:%u, dropping.\n"), + PRIP(ntohl(*(int*)&incoming.sin_addr)), + ntohs(incoming.sin_port)); FREE(mp->msg); FREE(mp); continue; @@ -315,37 +351,41 @@ &((char*)mp->msg)[size - sizeof(UDPMessage)], sizeof(UDPMessage)); - IFLOG(LOG_DEBUG, - hash2enc(&udpm.sender.hashPubKey, +#if DEBUG_UDP + GE_IFLOG(ectx, + GE_DEBUG | GE_USER | GE_BULK, + hash2enc(&udpm.sender.hashPubKey, &enc)); -#if DEBUG_UDP - LOG(LOG_DEBUG, - "received %d bytes via UDP from %u.%u.%u.%u:%u (%s)\n", - size, - PRIP(ntohl(*(int*)&incoming.sin_addr)), - ntohs(incoming.sin_port), - &enc); + GE_LOG(ectx, + GE_DEBUG | GE_USER | GE_BULK, + "received %d bytes via UDP from %u.%u.%u.%u:%u (%s)\n", + size, + PRIP(ntohl(*(int*)&incoming.sin_addr)), + ntohs(incoming.sin_port), + &enc); #endif /* quick test of the packet, if failed, repeat! */ if (size != ntohs(udpm.size)) { - LOG(LOG_WARNING, - _("Packet received from %u.%u.%u.%u:%u (UDP) failed format check.\n"), - PRIP(ntohl(*(int*)&incoming.sin_addr)), - ntohs(incoming.sin_port)); + GE_LOG(ectx, + GE_WARNING | GE_USER | GE_BULK, + _("Packet received from %u.%u.%u.%u:%u (UDP) failed format check.\n"), + PRIP(ntohl(*(int*)&incoming.sin_addr)), + ntohs(incoming.sin_port)); FREE(mp->msg); FREE(mp); continue; } - GNUNET_ASSERT(sizeof(struct in_addr) == sizeof(IPaddr)); + GE_ASSERT(ectx, sizeof(struct in_addr) == sizeof(IPaddr)); memcpy(&ipaddr, &incoming.sin_addr, sizeof(struct in_addr)); if (YES == isBlacklisted(ipaddr)) { - LOG(LOG_WARNING, - _("%s: Rejected connection from blacklisted " - "address %u.%u.%u.%u.\n"), - "UDP", - PRIP(ntohl(*(int*)&incoming.sin_addr))); + GE_LOG(ectx, + GE_WARNING | GE_USER | GE_BULK, + _("%s: Rejected connection from blacklisted " + "address %u.%u.%u.%u.\n"), + "UDP", + PRIP(ntohl(*(int*)&incoming.sin_addr))); FREE(mp->msg); FREE(mp); continue; @@ -384,7 +424,7 @@ return SYSERR; /* obviously invalid */ else { #if DEBUG_UDP - LOG(LOG_DEBUG, + GE_LOG(ectx, GE_DEBUG | GE_USER | GE_BULK, "Verified UDP helo from %u.%u.%u.%u:%u.\n", PRIP(ntohl(*(int*)&haddr->senderIP.addr)), ntohs(haddr->senderPort)); @@ -411,16 +451,20 @@ msg = MALLOC(sizeof(P2P_hello_MESSAGE) + sizeof(HostAddress)); haddr = (HostAddress*) &msg[1]; - if (SYSERR == getPublicIPAddress(&haddr->senderIP)) { + if (SYSERR == getPublicIPAddress(cfg, + ectx, + &haddr->senderIP)) { + GE_LOG(ectx, + GE_WARNING | GE_ADMIN | GE_BULK, + _("UDP: Could not determine my public IP address.\n")); FREE(msg); - LOG(LOG_WARNING, - _("UDP: Could not determine my public IP address.\n")); return NULL; } #if DEBUG_UDP - LOG(LOG_DEBUG, - "UDP uses IP address %u.%u.%u.%u.\n", - PRIP(ntohl(*(int*)&haddr->senderIP))); + GE_LOG(ectx, + GE_DEBUG | GE_USER | GE_BULK, + "UDP uses IP address %u.%u.%u.%u.\n", + PRIP(ntohl(*(int*)&haddr->senderIP))); #endif if (udp_shutdown == YES) haddr->senderPort = htons(getGNUnetUDPPort()); @@ -452,7 +496,7 @@ tsession->ttype = udpAPI.protocolNumber; haddr = (HostAddress*) &helo[1]; #if DEBUG_UDP - LOG(LOG_DEBUG, + GE_LOG(ectx, GE_DEBUG | GE_USER | GE_BULK, "Connecting via UDP to %u.%u.%u.%u:%u.\n", PRIP(ntohl(*(int*)&haddr->senderIP.addr)), ntohs(haddr->senderPort)); @@ -494,15 +538,16 @@ struct sockaddr_in sin; /* an Internet endpoint address */ int ok; int ssize; + size_t sent; if (udp_shutdown == YES) return SYSERR; if (size == 0) { - BREAK(); + GE_BREAK(ectx, 0); return SYSERR; } if (size > udpAPI.mtu) { - BREAK(); + GE_BREAK(ectx, 0); return SYSERR; } helo = (P2P_hello_MESSAGE*)tsession->internal; @@ -511,8 +556,8 @@ haddr = (HostAddress*) &helo[1]; ssize = size + sizeof(UDPMessage); - msg = MALLOC(ssize); - mp.size = htons(ssize); + msg = MALLOC(ssize); + mp.size = htons(ssize); mp.reserved = 0; mp.sender = *(coreAPI->myIdentity); memcpy(&msg[size], @@ -526,37 +571,38 @@ sin.sin_family = AF_INET; sin.sin_port = haddr->senderPort; - GNUNET_ASSERT(sizeof(struct in_addr) == sizeof(IPaddr)); + GE_ASSERT(ectx, sizeof(struct in_addr) == sizeof(IPaddr)); memcpy(&sin.sin_addr, &haddr->senderIP, sizeof(IPaddr)); #if DEBUG_UDP - LOG(LOG_DEBUG, + GE_LOG(ectx, GE_DEBUG | GE_USER | GE_BULK, "Sending message of %d bytes via UDP to %u.%u.%u.%u:%u.\n", ssize, PRIP(ntohl(*(int*)&sin.sin_addr)), ntohs(sin.sin_port)); #endif - if (ssize == SENDTO(udp_sock, - msg, - ssize, - 0, /* no flags */ - (struct sockaddr*) &sin, - sizeof(sin))) { + if (YES == socket_send_to(udp_sock, + NC_Nonblocking, + msg, + ssize, + &sent, + (struct sockaddr*) &sin, + sizeof(sin))) { ok = OK; stats->change(stat_bytesSent, - ssize); + sent); } else { - LOG(LOG_WARNING, - _("Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"), - ssize, - PRIP(ntohl(*(int*)&sin.sin_addr)), - ntohs(sin.sin_port), - STRERROR(errno)); + GE_LOG(ectx, + GE_WARNING | GE_ADMIN | GE_BULK, + _("Failed to send message of size %d via UDP to %u.%u.%u.%u:%u: %s\n"), + ssize, + PRIP(ntohl(*(int*)&sin.sin_addr)), + ntohs(sin.sin_port), + STRERROR(errno)); stats->change(stat_bytesDropped, ssize); } - incrementBytesSent(ssize); FREE(msg); return ok; } @@ -587,20 +633,16 @@ udp_sock = passivesock(port); if (port != 0) { udp_shutdown = NO; - serverSignal = SEMAPHORE_NEW(0); - if (0 != PTHREAD_CREATE(&dispatchThread, - (PThreadMain) &listenAndDistribute, - NULL, - 4*1024)) { - SEMAPHORE_FREE(serverSignal); + serverSignal = SEMAPHORE_CREATE(0); + dispatchThread = PTHREAD_CREATE(&listenAndDistribute, + NULL, + 5 * 1024); + if (dispatchThread == NULL) { + SEMAPHORE_DESTROY(serverSignal); serverSignal = NULL; return SYSERR; } - SEMAPHORE_DOWN(serverSignal); - } else { - memset(&dispatchThread, - 0, - sizeof(PTHREAD_T)); /* zero-out */ + SEMAPHORE_DOWN(serverSignal, YES); } return OK; } @@ -610,7 +652,7 @@ * restarted later! */ static int stopTransportServer() { - GNUNET_ASSERT(udp_sock != -1); + GE_ASSERT(ectx, udp_sock != NULL); if (udp_shutdown == NO) { /* stop the thread, first set shutdown to YES, then ensure that the thread @@ -625,7 +667,9 @@ mySock = SOCKET(PF_INET, SOCK_DGRAM, UDP_PROTOCOL_NUMBER); if (mySock < 0) - DIE_STRERROR("socket"); + GE_DIE_STRERROR(ectx, + GE_FATAL | GE_ADMIN | GE_IMMEDIATE, + "socket"); /* send to loopback */ sin.sin_family = AF_INET; sin.sin_port = htons(port); @@ -636,34 +680,38 @@ 0, (struct sockaddr*) &sin, sizeof(sin)); - PTHREAD_KILL(&dispatchThread, SIGALRM); /* sometimes LO is firewalled, try alternative */ - SEMAPHORE_DOWN(serverSignal); - SEMAPHORE_FREE(serverSignal); - PTHREAD_JOIN(&dispatchThread, &unused); + PTHREAD_STOP_SLEEP(dispatchThread); + SEMAPHORE_DOWN(serverSignal, YES); + SEMAPHORE_DESTROY(serverSignal); + PTHREAD_JOIN(dispatchThread, &unused); } } - closefile(udp_sock); - udp_sock = -1; + socket_destroy(udp_sock); + udp_sock = NULL; return OK; } /** * Reload the configuration. Should never fail. */ -static void reloadConfiguration(void) { +static void reloadConfiguration() { char * ch; - MUTEX_LOCK(&configLock); + MUTEX_LOCK(configLock); FREENONNULL(filteredNetworks_); - ch = getConfigurationString("UDP", - "BLACKLIST"); - if (ch == NULL) - filteredNetworks_ = parseRoutes(""); + if (0 != GC_get_configuration_value_string(cfg, + "UDP", + "BLACKLIST", + NULL, + &ch)) + filteredNetworks_ = parse_ipv4_network_specification(ectx, + ""); else { - filteredNetworks_ = parseRoutes(ch); + filteredNetworks_ = parse_ipv4_network_specification(ectx, + ch); FREE(ch); } - MUTEX_UNLOCK(&configLock); + MUTEX_UNLOCK(configLock); } /** @@ -696,11 +744,29 @@ * returns the udp transport API. */ TransportAPI * inittransport_udp(CoreAPIForTransport * core) { - int mtu; + unsigned long long mtu; - GNUNET_ASSERT(sizeof(HostAddress) == 8); - GNUNET_ASSERT(sizeof(UDPMessage) == 68); + ectx = core->ectx; + cfg = core->cfg; + load_monitor = core->load_monitor; + GE_ASSERT(ectx, sizeof(HostAddress) == 8); + GE_ASSERT(ectx, sizeof(UDPMessage) == 68); coreAPI = core; + if (-1 == GC_get_configuration_value_number(cfg, + "UDP", + "MTU", + sizeof(UDPMessage) + P2P_MESSAGE_OVERHEAD + sizeof(MESSAGE_HEADER) + 4, + 65500, + MESSAGE_SIZE, + &mtu)) { + return NULL; + } + if (mtu < 1200) + GE_LOG(ectx, + GE_ERROR | GE_USER | GE_IMMEDIATE, + _("MTU %llu for `%s' is probably too low!\n"), + mtu, + "UDP"); stats = coreAPI->requestService("stats"); if (stats != NULL) { stat_bytesReceived @@ -710,23 +776,13 @@ stat_bytesDropped = stats->create(gettext_noop("# bytes dropped by UDP (outgoing)")); } - - MUTEX_CREATE(&configLock); - reloadConfiguration(); - mtu = getConfigurationInt("UDP", - "MTU"); - if (mtu == 0) - mtu = MESSAGE_SIZE; - if (mtu < 1200) - LOG(LOG_ERROR, - _("MTU for `%s' is probably too low (fragmentation not implemented!)\n"), - "UDP"); - + configLock = MUTEX_CREATE(NO); + reloadConfiguration(); udpAPI.protocolNumber = UDP_PROTOCOL_NUMBER; udpAPI.mtu = mtu - sizeof(UDPMessage); udpAPI.cost = 20000; udpAPI.verifyHelo = &verifyHelo; - udpAPI.createhello = &createhello; + udpAPI.createhello = &createhello; udpAPI.connect = &udpConnect; udpAPI.send = &udpSend; udpAPI.sendReliable = &udpSend; /* can't increase reliability */ @@ -742,7 +798,8 @@ void donetransport_udp() { coreAPI->releaseService(stats); - MUTEX_DESTROY(&configLock); + MUTEX_DESTROY(configLock); + configLock = NULL; FREENONNULL(filteredNetworks_); coreAPI = NULL; } Modified: GNUnet/src/util/network/io.c =================================================================== --- GNUnet/src/util/network/io.c 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/src/util/network/io.c 2006-07-25 09:50:37 UTC (rev 3134) @@ -22,6 +22,8 @@ * @file util/network/io.c * @brief (network) input/output operations * @author Christian Grothoff + * + * TODO: load monitor support! */ #include "gnunet_util_network.h" @@ -183,6 +185,73 @@ return YES; } +int socket_recv_from(struct SocketHandle * s, + NC_KIND nc, + void * buf, + size_t max, + size_t * read, + struct sockaddr * from, + socklen_t * fromlen) { + int flags; + size_t pos; + size_t ret; + + socket_set_blocking(s, + 0 == (nc & NC_Blocking)); + flags = 0; +#ifdef CYGWIN + if (0 == (nc & NC_IgnoreInt)) + flags |= MSG_NOSIGNAL; +#elif OSX + /* anything? */ +#elif SOMEBSD || SOLARIS + if (0 == (nc & NC_Blocking)) + flags |= MSG_DONTWAIT; +#elif LINUX + if (0 == (nc & NC_Blocking)) + flags |= MSG_DONTWAIT; + if (0 == (nc & NC_IgnoreInt)) + flags |= MSG_NOSIGNAL; +#else + /* good luck */ +#endif + pos = 0; + do { + ret = (size_t) RECVFROM(s->handle, + &((char*)buf)[pos], + max - pos, + flags, + from, + fromlen); + if ( (ret == (size_t) -1) && + (errno == EINTR) && + (0 != (nc & NC_IgnoreInt)) ) + continue; + if (ret == (size_t) -1) { + if (errno == EINTR) { + *read = pos; + return YES; + } + if ( (errno == EAGAIN) || + (errno == EWOULDBLOCK) ) { + if (0 != (nc & NC_Blocking)) + continue; + *read = pos; + return (pos == 0) ? NO : YES; + } + GE_LOG_STRERROR(s->ectx, + GE_DEBUG | GE_USER | GE_REQUEST, + "recv"); + *read = pos; + return SYSERR; + } + pos += ret; + } while ( (pos < max) && + (0 != (nc & NC_Blocking)) ); + *read = pos; + return YES; +} + int socket_send(struct SocketHandle * s, NC_KIND nc, const void * buf, @@ -247,6 +316,74 @@ return YES; } +int socket_send_to(struct SocketHandle * s, + NC_KIND nc, + const void * buf, + size_t max, + size_t * sent, + const struct sockaddr * dst, + socklen_t dstlen) { + int flags; + size_t pos; + size_t ret; + + socket_set_blocking(s, + 0 == (nc & NC_Blocking)); + flags = 0; +#if SOMEBSD || SOLARIS + if (0 == (nc & NC_Blocking)) + flags |= MSG_DONTWAIT; +#elif OSX + /* As braindead as Win32? */ +#elif CYGWIN + if (0 == (nc & NC_IgnoreInt)) + flags |= MSG_NOSIGNAL; +#elif LINUX + if (0 == (nc & NC_Blocking)) + flags |= MSG_DONTWAIT; + if (0 == (nc & NC_IgnoreInt)) + flags |= MSG_NOSIGNAL; +#else + /* pray */ +#endif + + pos = 0; + do { + ret = (size_t) SENDTO(s->handle, + &((char*)buf)[pos], + max - pos, + flags, + dst, + dstlen); + if ( (ret == (size_t) -1) && + (errno == EINTR) && + (0 != (nc & NC_IgnoreInt)) ) + continue; + if (ret == (size_t) -1) { + if (errno == EINTR) { + *sent = pos; + return YES; + } + if ( (errno == EAGAIN) || + (errno == EWOULDBLOCK) ) { + if (0 != (nc & NC_Blocking)) + continue; + *sent = pos; + return (pos == 0) ? NO : YES; + } + GE_LOG_STRERROR(s->ectx, + GE_DEBUG | GE_USER | GE_REQUEST, + "send"); + *sent = pos; + return SYSERR; + } + pos += ret; + } while ( (pos < max) && + (0 != (nc & NC_Blocking)) ); + *sent = pos; + return YES; +} + /** * Check if socket is valid * @return 1 if valid, 0 otherwise Modified: GNUnet/todo =================================================================== --- GNUnet/todo 2006-07-25 09:03:10 UTC (rev 3133) +++ GNUnet/todo 2006-07-25 09:50:37 UTC (rev 3134) @@ -13,9 +13,12 @@ 0.7.1 ['06] (aka "stabilization") - finish util refactoring: + * util: + + network/io: load monitor support + + loggers: SMTP logger * transports: + TCP: setBlocking for select pipe - + UDP/SMTP/HTTP/IPv6: do not yet compile + + SMTP/HTTP/IPv6: do not yet compile * core: + nothing compiles + add support for extended core API fields _______________________________________________ GNUnet-SVN mailing list GNUnet-SVN@gnu.org http://lists.gnu.org/mailman/listinfo/gnunet-svn