diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/misc.c | 2 | ||||
-rw-r--r-- | src/core/net-nonblock.c | 18 | ||||
-rw-r--r-- | src/core/net-nonblock.h | 14 | ||||
-rw-r--r-- | src/core/network.c | 83 | ||||
-rw-r--r-- | src/core/network.h | 5 | ||||
-rw-r--r-- | src/core/server.c | 6 |
6 files changed, 101 insertions, 27 deletions
diff --git a/src/core/misc.c b/src/core/misc.c index 516c6dc3..78190db2 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -409,7 +409,7 @@ int match_wildcards(const char *cmask, const char *data) } ret = data != NULL && *data == '\0' && *mask == '\0'; - free(newmask); + g_free(newmask); return ret; } diff --git a/src/core/net-nonblock.c b/src/core/net-nonblock.c index b6e9264f..86d0f263 100644 --- a/src/core/net-nonblock.c +++ b/src/core/net-nonblock.c @@ -39,7 +39,7 @@ SIMPLE_THREAD_REC; /* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is written to pipe when found PID of the resolver child is returned */ -int net_gethostname_nonblock(const char *addr, int pipe) +int net_gethostbyname_nonblock(const char *addr, int pipe) { RESOLVED_IP_REC rec; const char *errorstr; @@ -60,7 +60,8 @@ int net_gethostname_nonblock(const char *addr, int pipe) } /* child */ - rec.error = net_gethostname(addr, &rec.ip); + memset(&rec, 0, sizeof(rec)); + rec.error = net_gethostbyname(addr, &rec.ip); if (rec.error == 0) { errorstr = NULL; } else { @@ -105,7 +106,7 @@ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec) if (rec->error) { /* read error string */ - rec->errorstr = g_malloc(rec->errlen); + rec->errorstr = g_malloc(rec->errlen+1); len = 0; do { ret = read(pipe, rec->errorstr+len, rec->errlen-len); @@ -122,6 +123,13 @@ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec) return 0; } +/* Get host name, call func when finished */ +int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data) +{ + /*FIXME*/ + return FALSE; +} + /* Kill the resolver child */ void net_disconnect_nonblock(int pid) { @@ -173,7 +181,7 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, int pipe) return; } - rec->tag = g_input_add(handle, G_INPUT_WRITE, + rec->tag = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, (GInputFunction) simple_init, rec); } @@ -192,7 +200,7 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip, NET_ } /* start nonblocking host name lookup */ - net_gethostname_nonblock(server, fd[1]); + net_gethostbyname_nonblock(server, fd[1]); rec = g_new0(SIMPLE_THREAD_REC, 1); rec->port = port; diff --git a/src/core/net-nonblock.h b/src/core/net-nonblock.h index 6ae05e82..6e4e10f4 100644 --- a/src/core/net-nonblock.h +++ b/src/core/net-nonblock.h @@ -11,10 +11,22 @@ typedef struct { need to free() it yourself unless it's NULL */ } RESOLVED_IP_REC; +typedef struct { + int namelen; + char *name; + + int error; + int errlen; + char *errorstr; +} RESOLVED_NAME_REC; + typedef void (*NET_CALLBACK) (int, void *); +typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *); /* nonblocking gethostbyname(), PID of the resolver child is returned. */ -int net_gethostname_nonblock(const char *addr, int pipe); +int net_gethostbyname_nonblock(const char *addr, int pipe); +/* Get host's name, call func when finished */ +int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data); /* get the resolved IP address. returns -1 if some error occured with read() */ int net_gethostbyname_return(int pipe, RESOLVED_IP_REC *rec); diff --git a/src/core/network.c b/src/core/network.c index d962f35f..55431971 100644 --- a/src/core/network.c +++ b/src/core/network.c @@ -50,7 +50,18 @@ int net_ip_compare(IPADDR *ip1, IPADDR *ip2) /* copy IP to sockaddr */ inline void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) { - so->sin.sin_family = ip->family; + if (ip == NULL) { +#ifdef HAVE_IPV6 + so->sin6.sin6_family = AF_INET6; + so->sin6.sin6_addr.s_addr = in6addr_any; +#else + so->sin.sin_family = AF_INET; + so->sin.sin_addr.s_addr = INADDR_ANY; +#endif + return; + } + + so->sin.sin_family = ip->family; #ifdef HAVE_IPV6 if (ip->family == AF_INET6) memcpy(&so->sin6.sin6_addr, &ip->addr, sizeof(ip->addr.ip6)); @@ -97,7 +108,7 @@ int net_connect(const char *addr, int port, IPADDR *my_ip) g_return_val_if_fail(addr != NULL, -1); - if (net_gethostname(addr, &ip) == -1) + if (net_gethostbyname(addr, &ip) == -1) return -1; return net_connect_ip(&ip, port, my_ip); @@ -149,21 +160,22 @@ void net_disconnect(int handle) close(handle); } -/* Listen for connections on a socket */ +/* Listen for connections on a socket. if `my_ip' is NULL, listen in any + address. */ int net_listen(IPADDR *my_ip, int *port) { union sockaddr_union so; int ret, handle, opt = 1; socklen_t len = sizeof(so); - g_return_val_if_fail(my_ip != NULL, -1); g_return_val_if_fail(port != NULL, -1); - /* create the socket */ memset(&so, 0, sizeof(so)); - so.sin.sin_family = my_ip->family; - handle = socket(my_ip->family, SOCK_STREAM, 0); + sin_set_port(&so, *port); + sin_set_ip(&so, my_ip); + /* create the socket */ + handle = socket(so.sin.sin_family, SOCK_STREAM, 0); if (handle == -1) return -1; @@ -173,7 +185,6 @@ int net_listen(IPADDR *my_ip, int *port) setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt)); /* specify the address/port we want to listen in */ - sin_set_port(&so, *port); ret = bind(handle, &so.sa, sizeof(so)); if (ret < 0) { close(handle); @@ -190,8 +201,7 @@ int net_listen(IPADDR *my_ip, int *port) *port = sin_get_port(&so); /* start listening */ - if (listen(handle, 1) < 0) - { + if (listen(handle, 1) < 0) { close(handle); return -1; } @@ -207,8 +217,6 @@ int net_accept(int handle, IPADDR *addr, int *port) socklen_t addrlen; g_return_val_if_fail(handle != -1, -1); - g_return_val_if_fail(addr != NULL, -1); - g_return_val_if_fail(port != NULL, -1); addrlen = sizeof(so); ret = accept(handle, &so.sa, &addrlen); @@ -216,8 +224,8 @@ int net_accept(int handle, IPADDR *addr, int *port) if (ret < 0) return -1; - sin_get_ip(&so, addr); - *port = sin_get_port(&so); + if (addr != NULL) sin_get_ip(&so, addr); + if (port != NULL) *port = sin_get_port(&so); fcntl(ret, F_SETFL, O_NONBLOCK); return ret; @@ -297,7 +305,7 @@ int net_getsockname(int handle, IPADDR *addr, int *port) /* Get IP address for host, returns 0 = ok, others = error code for net_gethosterror() */ -int net_gethostname(const char *addr, IPADDR *ip) +int net_gethostbyname(const char *addr, IPADDR *ip) { #ifdef HAVE_IPV6 union sockaddr_union *so; @@ -310,7 +318,6 @@ int net_gethostname(const char *addr, IPADDR *ip) g_return_val_if_fail(addr != NULL, -1); - /* host name */ #ifdef HAVE_IPV6 memset(ip, 0, sizeof(IPADDR)); memset(&req, 0, sizeof(struct addrinfo)); @@ -338,6 +345,50 @@ int net_gethostname(const char *addr, IPADDR *ip) return 0; } +/* Get name for host, *name should be g_free()'d unless it's NULL. + Return values are the same as with net_gethostbyname() */ +int net_gethostbyaddr(IPADDR *ip, char **name) +{ +#ifdef HAVE_IPV6 + struct addrinfo req, *ai; + char hbuf[NI_MAXHOST]; + int host_error; +#else + struct hostent *hp; +#endif + char ipname[MAX_IP_LEN]; + + g_return_val_if_fail(ip != NULL, -1); + g_return_val_if_fail(name != NULL, -1); + + *name = NULL; +#ifdef HAVE_IPV6 + memset(&req, 0, sizeof(struct addrinfo)); + req.ai_socktype = SOCK_STREAM; + + /* save error to host_error for later use */ + host_error = getaddrinfo(addr, NULL, &req, &ai); + if (host_error != 0) + return host_error; + + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, 0)) + return 1; + + /*FIXME: how does this work? *name = g_strdup(ai->???);*/ + freeaddrinfo(ai); + return 1; +#else + net_ip2host(ip, ipname); + + hp = gethostbyaddr(ipname, strlen(ipname), AF_INET); + if (hp == NULL) return -1; + + *name = g_strdup(hp->h_name); +#endif + + return 0; +} + int net_ip2host(IPADDR *ip, char *host) { #ifdef HAVE_IPV6 diff --git a/src/core/network.h b/src/core/network.h index a206da45..b7e6a30f 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -52,7 +52,10 @@ int net_transmit(int handle, const char *data, int len); /* Get IP address for host, returns 0 = ok, others = error code for net_gethosterror() */ -int net_gethostname(const char *addr, IPADDR *ip); +int net_gethostbyname(const char *addr, IPADDR *ip); +/* Get name for host, *name should be g_free()'d unless it's NULL. + Return values are the same as with net_gethostbyname() */ +int net_gethostbyaddr(IPADDR *ip, char **name); /* get error of net_gethostname() */ const char *net_gethosterror(int error); diff --git a/src/core/server.c b/src/core/server.c index a600e74a..07da183e 100644 --- a/src/core/server.c +++ b/src/core/server.c @@ -175,9 +175,9 @@ int server_connect(SERVER_REC *server) server->handle = -1; server->connect_pid = - net_gethostname_nonblock(server->connrec->proxy != NULL ? - server->connrec->proxy : server->connrec->address, - server->connect_pipe[1]); + net_gethostbyname_nonblock(server->connrec->proxy != NULL ? + server->connrec->proxy : server->connrec->address, + server->connect_pipe[1]); server->connect_tag = g_input_add(server->connect_pipe[0], G_INPUT_READ, |