From: Zoran V. <vas...@us...> - 2005-06-10 14:39:42
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18089 Modified Files: binder.c Log Message: Attempt to unify usage and call-conventions on various Ns_SockListenXXX and Ns_SockBindXXX calls for various protocols (tcp, udp, raw, unix). Also, parts not needed for windows build (pre-binding) are ifdef'ed out. Still open: handling of Unix-domain sockets on Windows. It might compile but will definitely not work because of the address parsing issues (windows files do not begin with slash). Index: binder.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/binder.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** binder.c 10 Jun 2005 14:09:18 -0000 1.5 --- binder.c 10 Jun 2005 14:39:26 -0000 1.6 *************** *** 39,50 **** #include "nsd.h" #include <sys/un.h> - /* - * Locals defined in this file - */ ! #ifndef _WIN32 ! static void PreBind(char *line); ! #endif static Tcl_HashTable preboundTcp; --- 39,47 ---- #include "nsd.h" #include <sys/un.h> ! /* ! * Local variables defined in this file ! */ static Tcl_HashTable preboundTcp; *************** *** 54,57 **** --- 51,58 ---- static Ns_Mutex lock; + #ifndef _WIN32 + static void PreBind(char *line); + #endif + /* *************** *** 60,65 **** * Ns_SockListenEx -- * ! * Create a new socket bound to the specified port and listening ! * for new connections. * * Results: --- 61,66 ---- * Ns_SockListenEx -- * ! * Create a new TCP socket bound to the specified port and ! * listening for new connections. * * Results: *************** *** 75,103 **** Ns_SockListenEx(char *address, int port, int backlog) { ! int err, sock = -1; struct sockaddr_in sa; - Tcl_HashEntry *hPtr; ! if (Ns_GetSockAddr(&sa, address, port) != NS_OK) { ! return -1; ! } ! Ns_MutexLock(&lock); ! hPtr = Tcl_FindHashEntry(&preboundTcp, (char *) &sa); ! if (hPtr != NULL) { ! sock = (int) Tcl_GetHashValue(hPtr); ! Tcl_DeleteHashEntry(hPtr); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! sock = Ns_SockBind(&sa); ! } ! if (sock != -1 && listen(sock, backlog) != 0) { ! err = errno; ! close(sock); ! errno = err; ! sock = -1; } ! return sock; } --- 76,106 ---- Ns_SockListenEx(char *address, int port, int backlog) { ! int sock = -1; struct sockaddr_in sa; ! if (Ns_GetSockAddr(&sa, address, port) == NS_OK) { ! Tcl_HashEntry *hPtr; ! Ns_MutexLock(&lock); ! hPtr = Tcl_FindHashEntry(&preboundTcp, (char *) &sa); ! if (hPtr != NULL) { ! sock = (int) Tcl_GetHashValue(hPtr); ! Tcl_DeleteHashEntry(hPtr); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! /* Not prebound, bind now */ ! sock = Ns_SockBind(&sa); ! } ! if (sock >= 0 && listen(sock, backlog) == -1) { ! /* Can't listen; close the opened socket */ ! int err = errno; ! close(sock); ! errno = err; ! sock = -1; ! Ns_SetSockErrno(err); ! } } ! return (SOCKET)sock; } *************** *** 106,112 **** *---------------------------------------------------------------------- * ! * Ns_SockBindUdp -- * ! * Create a UDP socket and bind it to the passed-in address. * * Results: --- 109,115 ---- *---------------------------------------------------------------------- * ! * Ns_SockListenUdp -- * ! * Listen on the UDP socket for the given IP address and port. * * Results: *************** *** 114,118 **** * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 117,121 ---- * * Side effects: ! * May create a new socket if none prebound. * *---------------------------------------------------------------------- *************** *** 120,139 **** SOCKET ! Ns_SockBindUdp(struct sockaddr_in *saPtr) { ! int sock, err, n = 1; ! ! sock = socket(AF_INET,SOCK_DGRAM, 0); ! if (sock < 0 ! || setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) < 0 ! || bind(sock,(struct sockaddr *)saPtr, sizeof(struct sockaddr_in)) < 0) { ! err = errno; ! close(sock); ! Ns_SetSockErrno(err); ! sock = -1; ! } ! return sock; } --- 123,147 ---- SOCKET ! Ns_SockListenUdp(char *address, int port) { ! int sock = -1; ! struct sockaddr_in sa; ! if (Ns_GetSockAddr(&sa, address, port) == NS_OK) { ! Tcl_HashEntry *hPtr; ! Ns_MutexLock(&lock); ! hPtr = Tcl_FindHashEntry(&preboundUdp, (char *) &sa); ! if (hPtr != NULL) { ! sock = (int) Tcl_GetHashValue(hPtr); ! Tcl_DeleteHashEntry(hPtr); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! /* Not prebound, bind now */ ! sock = Ns_SockBindUdp(&sa); ! } ! } ! return (SOCKET)sock; } *************** *** 142,148 **** *---------------------------------------------------------------------- * ! * Ns_SockRaw -- * ! * Helper routine for creating a raw socket * * Results: --- 150,156 ---- *---------------------------------------------------------------------- * ! * Ns_SockListenRaw -- * ! * Listen on the raw socket addressed by the given protocol. * * Results: *************** *** 150,154 **** * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 158,162 ---- * * Side effects: ! * May create a new socket if none prebound. * *---------------------------------------------------------------------- *************** *** 156,173 **** SOCKET ! Ns_SockRaw(int proto) { ! int sock, err; ! ! sock = socket(AF_INET,SOCK_RAW, proto); ! if (sock < 0) { ! err = errno; ! close(sock); ! Ns_SetSockErrno(err); ! sock = -1; ! } ! return sock; } --- 164,190 ---- SOCKET ! Ns_SockListenRaw(int proto) { ! int sock = -1; ! Tcl_HashEntry *hPtr; ! Tcl_HashSearch search; ! Ns_MutexLock(&lock); ! hPtr = Tcl_FirstHashEntry(&preboundRaw, &search); ! while (hPtr != NULL) { ! if (proto == (int)Tcl_GetHashValue(hPtr)) { ! sock = (int)Tcl_GetHashKey(&preboundRaw, hPtr); ! Tcl_DeleteHashEntry(hPtr); ! break; ! } ! hPtr = Tcl_NextHashEntry(&search); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! /* Not prebound, bind now */ ! sock = Ns_SockBindRaw(proto); ! } ! return (SOCKET)sock; } *************** *** 176,183 **** *---------------------------------------------------------------------- * ! * Ns_SockListenUdp -- * ! * Create a new UDP socket bound to the specified port and ! * listening for new connections. * * Results: --- 193,199 ---- *---------------------------------------------------------------------- * ! * Ns_SockListenUnix -- * ! * Listen on the Unix-domain socket addressed by the given path. * * Results: *************** *** 185,189 **** * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 201,205 ---- * * Side effects: ! * May create a new socket if none prebound. * *---------------------------------------------------------------------- *************** *** 191,215 **** SOCKET ! Ns_SockListenUdp(char *address, int port) { int sock = -1; - struct sockaddr_in sa; Tcl_HashEntry *hPtr; - if (Ns_GetSockAddr(&sa, address, port) != NS_OK) { - return -1; - } Ns_MutexLock(&lock); ! hPtr = Tcl_FindHashEntry(&preboundUdp, (char *) &sa); ! if (hPtr != NULL) { ! sock = (int) Tcl_GetHashValue(hPtr); ! Tcl_DeleteHashEntry(hPtr); } Ns_MutexUnlock(&lock); if (hPtr == NULL) { ! sock = Ns_SockBindUdp(&sa); } ! return sock; } --- 207,233 ---- SOCKET ! Ns_SockListenUnix(char *path) { int sock = -1; Tcl_HashEntry *hPtr; + Tcl_HashSearch search; Ns_MutexLock(&lock); ! hPtr = Tcl_FirstHashEntry(&preboundUnix, &search); ! while (hPtr != NULL) { ! if (!strcmp(path, (char*)Tcl_GetHashValue(hPtr))) { ! sock = (int)Tcl_GetHashKey(&preboundRaw, hPtr); ! Tcl_DeleteHashEntry(hPtr); ! break; ! } ! hPtr = Tcl_NextHashEntry(&search); } Ns_MutexUnlock(&lock); if (hPtr == NULL) { ! /* Not prebound, bind now */ ! sock = Ns_SockBindUnix(path); } ! return (SOCKET)sock; } *************** *** 218,224 **** *---------------------------------------------------------------------- * ! * Ns_SockListenRaw -- * ! * Create a new RAW socket * * Results: --- 236,242 ---- *---------------------------------------------------------------------- * ! * Ns_SockBindUdp -- * ! * Create a UDP socket and bind it to the passed-in address. * * Results: *************** *** 232,257 **** SOCKET ! Ns_SockListenRaw(int proto) { ! int sock = -1; ! Tcl_HashEntry *hPtr; ! Tcl_HashSearch search; ! Ns_MutexLock(&lock); ! hPtr = Tcl_FirstHashEntry(&preboundRaw, &search); ! while (hPtr != NULL) { ! if (proto == (int)Tcl_GetHashValue(hPtr)) { ! sock = (int)Tcl_GetHashKey(&preboundRaw, hPtr); ! Tcl_DeleteHashEntry(hPtr); ! break; ! } ! hPtr = Tcl_NextHashEntry(&search); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! sock = Ns_SockRaw(proto); ! } ! return sock; } --- 250,269 ---- SOCKET ! Ns_SockBindUdp(struct sockaddr_in *saPtr) { ! int sock = -1, n = 1; ! ! sock = socket(AF_INET,SOCK_DGRAM, 0); ! if (sock == -1 ! || setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&n,sizeof(n)) == -1 ! || bind(sock,(struct sockaddr*)saPtr,sizeof(struct sockaddr_in)) == -1) { ! int err = errno; ! close(sock); ! sock = -1; ! Ns_SetSockErrno(err); ! } ! return (SOCKET)sock; } *************** *** 262,266 **** * Ns_SockBindUnix -- * ! * Helper routine for creating a listening UNIX domain socket. * * Results: --- 274,279 ---- * Ns_SockBindUnix -- * ! * Create a Unix-domain socket and bind it to the passed-in ! * file path. * * Results: *************** *** 276,297 **** Ns_SockBindUnix(char *path) { ! int sock, err; ! struct sockaddr_un addr; ! ! memset(&addr, 0, sizeof(addr)); ! addr.sun_family = AF_UNIX; ! strncpy(addr.sun_path,path, sizeof(addr.sun_path) - 1); ! unlink(path); ! ! sock = socket(AF_UNIX,SOCK_STREAM, 0); ! if (sock < 0 ! || bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { ! err = errno; ! close(sock); ! Ns_SetSockErrno(err); ! sock = -1; ! } ! ! return sock; } --- 289,311 ---- Ns_SockBindUnix(char *path) { ! int sock = -1; ! struct sockaddr_un addr; ! ! memset(&addr, 0, sizeof(addr)); ! addr.sun_family = AF_UNIX; ! strncpy(addr.sun_path,path, sizeof(addr.sun_path) - 1); ! unlink(path); ! ! sock = socket(AF_UNIX,SOCK_STREAM, 0); ! ! if (sock == -1 ! || bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { ! int err = errno; ! close(sock); ! sock = -1; ! Ns_SetSockErrno(err); ! } ! ! return (SOCKET)sock; } *************** *** 300,307 **** *---------------------------------------------------------------------- * ! * Ns_SockListenUnix -- * ! * Create a new Unix domain socket bound to the specified path and ! * listening for new connections. * * Results: --- 314,322 ---- *---------------------------------------------------------------------- * ! * Ns_SockBindRaw -- * ! * Create a raw socket. It does not bind, hence the call name ! * is not entirely correct but is on-pair with other types of ! * sockets (udp, tcp, unix). * * Results: *************** *** 315,335 **** SOCKET ! Ns_SockListenUnix(char *path) { ! int sock = -1; ! Tcl_HashEntry *hPtr; ! Ns_MutexLock(&lock); ! hPtr = Tcl_FindHashEntry(&preboundUnix, path); ! if (hPtr != NULL) { ! sock = (int)Tcl_GetHashKey(&preboundUnix, hPtr); ! Tcl_DeleteHashEntry(hPtr); ! } ! Ns_MutexUnlock(&lock); ! if (hPtr == NULL) { ! sock = Ns_SockBindUnix(path); ! } ! return sock; } --- 330,346 ---- SOCKET ! Ns_SockBindRaw(int proto) { ! int sock = -1; ! ! sock = socket(AF_INET,SOCK_RAW, proto); ! if (sock == -1) { ! int err = errno; ! close(sock); ! Ns_SetSockErrno(err); ! } ! return (SOCKET)sock; } *************** *** 340,344 **** * NsInitBinder -- * ! * Initialize the pre-bind table. * * Results: --- 351,355 ---- * NsInitBinder -- * ! * Initialize the pre-bind tables. * * Results: *************** *** 368,372 **** * NsPreBind -- * ! * Pre-bind any requested ports, called from Ns_Main at startup. * * Results: --- 379,383 ---- * NsPreBind -- * ! * Pre-bind any requested ports (called from Ns_Main at startup). * * Results: *************** *** 382,396 **** NsPreBind(char *args, char *file) { - char line[1024]; - FILE *fp; - if (args != NULL) { PreBind(args); } ! if (file != NULL && (fp = fopen(file, "r")) != NULL) { ! while (fgets(line, sizeof(line), fp) != NULL) { ! PreBind(line); } - fclose(fp); } } --- 393,409 ---- NsPreBind(char *args, char *file) { if (args != NULL) { PreBind(args); } ! if (file != NULL) { ! FILE *fp; ! fp = fopen(file, "r"); ! if (fp != NULL) { ! char line[1024]; ! while (fgets(line, sizeof(line), fp) != NULL) { ! PreBind(line); ! } ! fclose(fp); } } } *************** *** 402,406 **** * NsClosePreBound -- * ! * Close any remaining pre-bound sockets. * * Results: --- 415,419 ---- * NsClosePreBound -- * ! * Close remaining pre-bound sockets not consumed by anybody. * * Results: *************** *** 408,412 **** * * Side effects: ! * Pre-bound sockets closed. * *---------------------------------------------------------------------- --- 421,425 ---- * * Side effects: ! * Pre-bind hash-tables are cleaned and re-initialized. * *---------------------------------------------------------------------- *************** *** 424,427 **** --- 437,444 ---- Ns_MutexLock(&lock); + /* + * Close TCP sockets + */ + hPtr = Tcl_FirstHashEntry(&preboundTcp, &search); while (hPtr != NULL) { *************** *** 430,435 **** port = htons(saPtr->sin_port); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused TCP: %s:%d = %d", addr, port, sock); close(sock); hPtr = Tcl_NextHashEntry(&search); } --- 447,454 ---- port = htons(saPtr->sin_port); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused TCP socket: %s:%d = %d", ! addr, port, sock); close(sock); + Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } *************** *** 437,440 **** --- 456,463 ---- Tcl_InitHashTable(&preboundTcp, sizeof(struct sockaddr_in)/sizeof(int)); + /* + * Close UDP sockets + */ + hPtr = Tcl_FirstHashEntry(&preboundUdp, &search); while (hPtr != NULL) { *************** *** 443,448 **** port = htons(saPtr->sin_port); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused UDP: %s:%d = %d", addr, port, sock); close(sock); hPtr = Tcl_NextHashEntry(&search); } --- 466,473 ---- port = htons(saPtr->sin_port); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused UDP socket: %s:%d = %d", ! addr, port, sock); close(sock); + Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } *************** *** 450,459 **** Tcl_InitHashTable(&preboundUdp, sizeof(struct sockaddr_in)/sizeof(int)); hPtr = Tcl_FirstHashEntry(&preboundRaw, &search); while (hPtr != NULL) { sock = (int)Tcl_GetHashKey(&preboundRaw, hPtr); port = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused RAW: %d = %d", port, sock); close(sock); hPtr = Tcl_NextHashEntry(&search); } --- 475,490 ---- Tcl_InitHashTable(&preboundUdp, sizeof(struct sockaddr_in)/sizeof(int)); + /* + * Close raw sockets + */ + hPtr = Tcl_FirstHashEntry(&preboundRaw, &search); while (hPtr != NULL) { sock = (int)Tcl_GetHashKey(&preboundRaw, hPtr); port = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused raw socket: %d = %d", ! port, sock); close(sock); + Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } *************** *** 461,470 **** Tcl_InitHashTable(&preboundRaw, TCL_ONE_WORD_KEYS); hPtr = Tcl_FirstHashEntry(&preboundUnix, &search); while (hPtr != NULL) { addr = (char *) Tcl_GetHashKey(&preboundUnix, hPtr); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused Unix: %s = %d", addr, sock); close(sock); hPtr = Tcl_NextHashEntry(&search); } --- 492,507 ---- Tcl_InitHashTable(&preboundRaw, TCL_ONE_WORD_KEYS); + /* + * Close Unix-domain sockets + */ + hPtr = Tcl_FirstHashEntry(&preboundUnix, &search); while (hPtr != NULL) { addr = (char *) Tcl_GetHashKey(&preboundUnix, hPtr); sock = (int)Tcl_GetHashValue(hPtr); ! Ns_Log(Warning, "prebind: closed unused Unix-domain socket: %s = %d", ! addr, sock); close(sock); + Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } *************** *** 493,497 **** * Side effects: * Sockets are left in bound state for later listen ! * in Ns_SockListen. * *---------------------------------------------------------------------- --- 530,534 ---- * Side effects: * Sockets are left in bound state for later listen ! * in Ns_SockListenXXX. * *---------------------------------------------------------------------- *************** *** 584,588 **** } while(count--) { ! sock = Ns_SockRaw(IPPROTO_ICMP); if (sock == -1) { Ns_Log(Error, "prebind: icmp: %s",strerror(errno)); --- 621,625 ---- } while(count--) { ! sock = Ns_SockBindRaw(IPPROTO_ICMP); if (sock == -1) { Ns_Log(Error, "prebind: icmp: %s",strerror(errno)); *************** *** 590,594 **** } hPtr = Tcl_CreateHashEntry(&preboundRaw, (char *) sock, &new); ! if(!new) { Ns_Log(Error, "prebind: icmp: duplicate entry"); close(sock); --- 627,631 ---- } hPtr = Tcl_CreateHashEntry(&preboundRaw, (char *) sock, &new); ! if (!new) { Ns_Log(Error, "prebind: icmp: duplicate entry"); close(sock); *************** *** 606,610 **** continue; } ! sock = Ns_SockListenUnix(line); if (sock == -1) { Ns_Log(Error, "prebind: unix: %s: %s", proto, strerror(errno)); --- 643,647 ---- continue; } ! sock = Ns_SockBindUnix(line); if (sock == -1) { Ns_Log(Error, "prebind: unix: %s: %s", proto, strerror(errno)); |