From c461b473c13c9bca9dee58d9aebf548b5f5b4379 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Fri, 2 Dec 2011 22:26:49 +0000 Subject: [PATCH] Support IPv6 in server-bones examples. --- org.glite.lb.server/src/bkserverd.c | 67 +--------------------- .../examples/cnt_example.c | 60 ++++++++++++------- .../examples/srv_example.c | 40 +++---------- .../interface/srvbones.h | 7 +++ org.glite.lbjp-common.server-bones/src/srvbones.c | 61 ++++++++++++++++++++ 5 files changed, 119 insertions(+), 116 deletions(-) diff --git a/org.glite.lb.server/src/bkserverd.c b/org.glite.lb.server/src/bkserverd.c index 802972f..c6b9055 100644 --- a/org.glite.lb.server/src/bkserverd.c +++ b/org.glite.lb.server/src/bkserverd.c @@ -139,8 +139,6 @@ extern void _start (void), etext (void); int enable_lcas = 0; int debug = 0; int rgma_export = 0; -static const int one = 1; -static const int zero = 0; static int noAuth = 0; static int noIndex = 0; static int strict_locking = 0; @@ -305,7 +303,6 @@ static int asyn_gethostbyaddr(char **, char **, const struct sockaddr *, int, st static int add_root(edg_wll_Context, char *, authz_action); static int parse_limits(char *, int *, int *, int *); static int check_mkdir(const char *); -static int daemon_listen(const char *name, char *port, int *conn_out); /* @@ -644,19 +641,19 @@ int main(int argc, char *argv[]) } if ((mode & SERVICE_SERVER)) { - if (daemon_listen(NULL, port, &service_table[SRV_SERVE].conn) != 0) { + if (glite_srvbones_daemon_listen(NULL, port, &service_table[SRV_SERVE].conn) != 0) { return 1; } asprintf(&portstr, "%d", atoi(port)+1); - if (daemon_listen(NULL, portstr, &service_table[SRV_STORE].conn) != 0) { + if (glite_srvbones_daemon_listen(NULL, portstr, &service_table[SRV_STORE].conn) != 0) { free(portstr); return 1; } free(portstr); portstr = NULL; #ifdef GLITE_LB_SERVER_WITH_WS - if (daemon_listen(NULL, ws_port, &service_table[SRV_WS].conn) != 0) + if (glite_srvbones_daemon_listen(NULL, ws_port, &service_table[SRV_WS].conn) != 0) return 1; #endif /* GLITE_LB_SERVER_WITH_WS */ @@ -1956,61 +1953,3 @@ static int decrement_timeout(struct timeval *timeout, struct timeval before, str if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1); else return(0); } - -static int daemon_listen(const char *name, char *port, int *conn_out) { - struct addrinfo *ai; - struct addrinfo hints; - int conn; - int gaie; - - memset (&hints, '\0', sizeof (hints)); - hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG; - hints.ai_socktype = SOCK_STREAM; - hints.ai_family = AF_INET6; - - gaie = getaddrinfo (name, port, &hints, &ai); - if (gaie != 0 || ai == NULL) { - hints.ai_family = 0; - gaie = getaddrinfo (NULL, port, &hints, &ai); - } - - gaie = getaddrinfo (name, port, &hints, &ai); - if (gaie != 0) { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (gaie)); - return 1; - } - if (ai == NULL) { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no result"); - return 1; - } - - conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if ( conn < 0 ) { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "socket(): %s", strerror(errno)); - freeaddrinfo(ai); - return 1; - } - setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - if (ai->ai_family == AF_INET6) - setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); - - if ( bind(conn, ai->ai_addr, ai->ai_addrlen) ) - { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%s): %s", port, strerror(errno)); - close(conn); - freeaddrinfo(ai); - return 1; - } - - if ( listen(conn, CON_QUEUE) ) { - glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen(): %s", strerror(errno)); - close(conn); - freeaddrinfo(ai); - return 1; - } - - freeaddrinfo(ai); - - *conn_out = conn; - return 0; -} diff --git a/org.glite.lbjp-common.server-bones/examples/cnt_example.c b/org.glite.lbjp-common.server-bones/examples/cnt_example.c index 22f2bf2..ae32eb0 100644 --- a/org.glite.lbjp-common.server-bones/examples/cnt_example.c +++ b/org.glite.lbjp-common.server-bones/examples/cnt_example.c @@ -23,8 +23,7 @@ limitations under the License. #include #include #include -#include -#include +#include #ifndef dprintf #define dprintf(x) { if (debug) printf x; fflush(stdout); } @@ -59,14 +58,41 @@ static void usage(char *me) } +static int try_connect(char *addr, char *port) { + struct addrinfo hints; + struct addrinfo *ai_all = NULL, *ai; + int gaie, sock = -1; + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST | AI_NUMERICSERV; + gaie = getaddrinfo(addr, port, &hints, &ai_all); + if (gaie != 0 || !ai_all) return -1; + + for (ai = ai_all; ai; ai = ai->ai_next) { + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock == -1) continue; + if (connect(sock, ai->ai_addr, ai->ai_addrlen) == 0) { + break; + } else { + close(sock); + sock = -1; + } + } + freeaddrinfo(ai_all); + + return sock; +} + + int main(int argc, char **argv) { - struct sockaddr_in addr; - char buff[512], - *me; - int opt, - sock, - n; + char portstr[10]; + char buff[512], + *me; + int opt, + sock = -1, + n; int repeat = 1; me = strrchr(argv[0], '/'); @@ -88,20 +114,14 @@ int main(int argc, char **argv) } } - bzero((char *) &addr, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = htons(port); - if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) - { - perror("socket"); - exit(1); - } - if ( connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) - { - perror("connect"); + snprintf(portstr, sizeof(portstr), "%d", port); + + if ((sock = try_connect("127.0.0.1", portstr)) == -1 && + (sock = try_connect("::1", portstr)) == -1) { + fprintf(stderr, "can't connect\n"); exit(1); } + n = strlen(msg? msg: DEF_MSG); for (;repeat; repeat--) { if ( writen(sock, msg? msg: DEF_MSG, n) != n ) diff --git a/org.glite.lbjp-common.server-bones/examples/srv_example.c b/org.glite.lbjp-common.server-bones/examples/srv_example.c index 8cae54c..c54eb85 100644 --- a/org.glite.lbjp-common.server-bones/examples/srv_example.c +++ b/org.glite.lbjp-common.server-bones/examples/srv_example.c @@ -26,6 +26,7 @@ limitations under the License. #include #include +#include "glite/lbu/log.h" #include "srvbones.h" #ifndef dprintf @@ -46,8 +47,8 @@ static int disconnect(int, struct timeval *, void *); static int echo(int, struct timeval *, void *); static int upper_echo(int, struct timeval *, void *); -#define ECHO_PORT 9999 -#define UPPER_ECHO_PORT 9998 +#define ECHO_PORT "9999" +#define UPPER_ECHO_PORT "9998" #define SRV_ECHO 0 #define SRV_UPPER_ECHO 1 @@ -59,47 +60,22 @@ static struct glite_srvbones_service service_table[] = { int main(void) { - struct sockaddr_in myaddr; - - - if ( ((service_table[SRV_ECHO].conn = socket(AF_INET, SOCK_STREAM, 0)) == -1) - || ((service_table[SRV_UPPER_ECHO].conn = socket(AF_INET, SOCK_STREAM, 0)) == -1) ) - { - perror("socket"); + if (glite_common_log_init()) { + fprintf(stderr,"glite_common_log_init() failed, exiting."); exit(1); } - bzero((char *) &myaddr, sizeof(myaddr)); - myaddr.sin_family = AF_INET; - myaddr.sin_addr.s_addr = htonl(INADDR_ANY); - myaddr.sin_port = htons(ECHO_PORT); - if ( bind(service_table[SRV_ECHO].conn, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1 ) - { - perror("bind"); + if (glite_srvbones_daemon_listen(NULL, ECHO_PORT, &service_table[SRV_ECHO].conn) != 0) exit(1); - } - bzero((char *) &myaddr, sizeof(myaddr)); - myaddr.sin_family = AF_INET; - myaddr.sin_addr.s_addr = htonl(INADDR_ANY); - myaddr.sin_port = htons(UPPER_ECHO_PORT); - if ( bind(service_table[SRV_UPPER_ECHO].conn, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1 ) - { - perror("bind"); - exit(1); - } - if ( listen(service_table[SRV_ECHO].conn, 10) - || listen(service_table[SRV_UPPER_ECHO].conn, 10) ) - { - perror("listen()"); + if (glite_srvbones_daemon_listen(NULL, UPPER_ECHO_PORT, &service_table[SRV_UPPER_ECHO].conn) != 0) { + close(service_table[SRV_ECHO].conn); exit(1); } - glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_COUNT, 1); glite_srvbones_run(NULL, service_table, sizofa(service_table), 1); - return 0; } diff --git a/org.glite.lbjp-common.server-bones/interface/srvbones.h b/org.glite.lbjp-common.server-bones/interface/srvbones.h index 5244066..f3b428c 100644 --- a/org.glite.lbjp-common.server-bones/interface/srvbones.h +++ b/org.glite.lbjp-common.server-bones/interface/srvbones.h @@ -110,6 +110,13 @@ extern int glite_srvbones_run( */ int glite_srvbones_daemonize(const char *servername, const char *custom_pidfile, const char *custom_logfile); +/** + * Create listening socket. + * + * \return 0 OK, non-zero error + */ +int glite_srvbones_daemon_listen(const char *name, char *port, int *conn_out); + #ifdef __cplusplus } #endif diff --git a/org.glite.lbjp-common.server-bones/src/srvbones.c b/org.glite.lbjp-common.server-bones/src/srvbones.c index dd41c39..0510cd7 100644 --- a/org.glite.lbjp-common.server-bones/src/srvbones.c +++ b/org.glite.lbjp-common.server-bones/src/srvbones.c @@ -46,6 +46,7 @@ limitations under the License. #define REQUEST_TIMEOUT 10 /* timeout for a single request */ #define NEW_CLIENT_DURATION 10 /* how long a client is considered new, i.e. busy connection is not closed to serve other clients */ +#define CON_QUEUE 10 /* listen() connection queue */ #ifdef LB_PROF extern void _start (void), etext (void); @@ -324,6 +325,66 @@ int glite_srvbones_daemonize(const char *servername, const char *custom_pidfile, return 1; } +int glite_srvbones_daemon_listen(const char *name, char *port, int *conn_out) { + struct addrinfo *ai; + struct addrinfo hints; + int conn; + int gaie; + static const int zero = 0; + static const int one = 1; + + memset (&hints, '\0', sizeof (hints)); + hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG; + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_INET6; + + gaie = getaddrinfo (name, port, &hints, &ai); + if (gaie != 0 || ai == NULL) { + hints.ai_family = 0; + gaie = getaddrinfo (NULL, port, &hints, &ai); + } + + gaie = getaddrinfo (name, port, &hints, &ai); + if (gaie != 0) { + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (gaie)); + return 1; + } + if (ai == NULL) { + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no result"); + return 1; + } + + conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if ( conn < 0 ) { + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "socket(): %s", strerror(errno)); + freeaddrinfo(ai); + return 1; + } + setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + if (ai->ai_family == AF_INET6) + setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); + + if ( bind(conn, ai->ai_addr, ai->ai_addrlen) ) + { + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%s): %s", port, strerror(errno)); + close(conn); + freeaddrinfo(ai); + return 1; + } + + if ( listen(conn, CON_QUEUE) ) { + glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen(): %s", strerror(errno)); + close(conn); + freeaddrinfo(ai); + return 1; + } + + freeaddrinfo(ai); + + *conn_out = conn; + return 0; +} + static int dispatchit(int sock_slave, int sock, int sidx) { struct sockaddr_storage a; -- 1.8.2.3