summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/misc.c2
-rw-r--r--src/core/net-nonblock.c18
-rw-r--r--src/core/net-nonblock.h14
-rw-r--r--src/core/network.c83
-rw-r--r--src/core/network.h5
-rw-r--r--src/core/server.c6
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,