libixp

git clone git://oldgit.suckless.org/libixp/
Log | Files | Refs | LICENSE

commit 0b3d92b799ddfac0f39c30ce208ae70025e3ea4a
parent f2e724d0156a2b12ba34e04de42a3aa20cc5d45f
Author: Kris Maglione <jg@suckless.org>
Date:   Thu,  5 Jul 2007 14:37:50 -0400

Resolve port names.

Diffstat:
libixp/socket.c | 134+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
libixp_rubythread/thread_ruby.c | 4++--
2 files changed, 82 insertions(+), 56 deletions(-)

diff --git a/libixp/socket.c b/libixp/socket.c @@ -20,28 +20,27 @@ * not modified. */ +typedef struct addrinfo addrinfo; typedef struct sockaddr sockaddr; typedef struct sockaddr_un sockaddr_un; typedef struct sockaddr_in sockaddr_in; -static int +static char* get_port(char *addr) { - char *s, *end; - int port; + char *s; s = strchr(addr, '!'); if(s == nil) { werrstr("no port provided"); - return -1; + return nil; } *s++ = '\0'; - port = strtol(s, &end, 10); - if(*s == '\0' && *end != '\0') { + if(*s == '\0') { werrstr("invalid port number"); - return -1; + return nil; } - return port; + return s; } static int @@ -61,34 +60,6 @@ sock_unix(char *address, sockaddr_un *sa, socklen_t *salen) { } static int -sock_tcp(char *host, sockaddr_in *sa) { - struct hostent *he; - int port, fd; - - /* Truncates host at '!' */ - port = get_port(host); - if(port < 0) - return -1; - - signal(SIGPIPE, SIG_IGN); - fd = socket(AF_INET, SOCK_STREAM, 0); - if(fd < 0) - return -1; - - memset(sa, 0, sizeof(sa)); - sa->sin_family = AF_INET; - sa->sin_port = htons(port); - - if(strcmp(host, "*") == 0) - sa->sin_addr.s_addr = htonl(INADDR_ANY); - else if((he = gethostbyname(host))) - memcpy(&sa->sin_addr, he->h_addr, he->h_length); - else - return -1; - return fd; -} - -static int dial_unix(char *address) { sockaddr_un sa; socklen_t salen; @@ -136,46 +107,100 @@ fail: return -1; } +static addrinfo* +alookup(char *host, int announce) { + addrinfo hints, *ret; + char *port; + int err; + + /* Truncates host at '!' */ + port = get_port(host); + if(port == nil) + return nil; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + if(announce) { + hints.ai_flags = AI_PASSIVE; + if(!strcmp(host, "*")) + host = nil; + } + + err = getaddrinfo(host, port, &hints, &ret); + if(err) { + werrstr("getaddrinfo: %s", gai_strerror(err)); + return nil; + } + return ret; +} + +static int +ai_socket(addrinfo *ai) { + return socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); +} + static int dial_tcp(char *host) { - sockaddr_in sa; + addrinfo *ai, *aip; int fd; - fd = sock_tcp(host, &sa); - if(fd == -1) - return fd; + aip = alookup(host, 0); + if(aip == nil) + return -1; + + for(ai = aip; ai; ai = ai->ai_next) { + fd = ai_socket(ai); + if(fd == -1) { + werrstr("socket: %s", strerror(errno)); + continue; + } - if(connect(fd, (sockaddr*)&sa, sizeof(sa))) { + if(connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) + break; + + werrstr("connect: %s", strerror(errno)); close(fd); - return -1; + fd = -1; } + freeaddrinfo(aip); return fd; } static int announce_tcp(char *host) { - sockaddr_in sa; + addrinfo *ai, *aip; int fd; - fd = sock_tcp(host, &sa); - if(fd == -1) - return fd; + aip = alookup(host, 1); + if(aip == nil) + return -1; - if(bind(fd, (sockaddr*)&sa, sizeof(sa)) < 0) - goto fail; + /* Probably don't need to loop */ + for(ai = aip; ai; ai = ai->ai_next) { + fd = ai_socket(ai); + if(fd == -1) + continue; - if(listen(fd, IXP_MAX_CACHE) < 0) - goto fail; + if(bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) + goto fail; - return fd; + if(listen(fd, IXP_MAX_CACHE) < 0) + goto fail; + break; + fail: + close(fd); + fd = -1; + } -fail: - close(fd); - return -1; + freeaddrinfo(aip); + return fd; } typedef struct addrtab addrtab; +static struct addrtab { char *type; int (*fn)(char*); @@ -223,3 +248,4 @@ int ixp_announce(char *address) { return lookup(address, atab); } + diff --git a/libixp_rubythread/thread_ruby.c b/libixp_rubythread/thread_ruby.c @@ -9,8 +9,7 @@ static char RWLock[]; int ixp_rubyinit(void) { - if(rb_require("thread.rb") != Qtrue) - return 1; + rb_require("thread.rb"); rb_eval_string(RWLock); ixp_thread = &ixp_rthread; return 0; @@ -264,3 +263,4 @@ static char RWLock[] = " Thread.critical = cr \n" " end \n" "end \n"; +