Respect the user preference

Try to resolve the address using the user-specified ip version and fail
gracefully if the network doesn't support it.
This commit is contained in:
LemonBoy 2015-09-23 15:37:23 +02:00
commit 32c33357d3
8 changed files with 23 additions and 19 deletions

View file

@ -130,7 +130,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
if (host != NULL && *host != '\0') {
IPADDR ip;
if (net_gethostbyname(host, &ip) == 0)
if (net_gethostbyname(host, &ip, conn->family) == 0)
server_connect_own_ip_save(conn, &ip);
}

View file

@ -73,7 +73,7 @@ static int g_io_channel_read_block(GIOChannel *channel, void *data, int len)
/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is
written to pipe when found PID of the resolver child is returned */
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
int reverse_lookup)
int family, int reverse_lookup)
{
RESOLVED_IP_REC rec;
const char *errorstr;
@ -103,7 +103,7 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
srand(time(NULL));
memset(&rec, 0, sizeof(rec));
rec.error = net_gethostbyname(addr, &rec.ip);
rec.error = net_gethostbyname(addr, &rec.ip, family);
if (rec.error == 0) {
errorstr = NULL;
if (reverse_lookup) {
@ -267,7 +267,7 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
rec->pipes[1] = g_io_channel_new(fd[1]);
/* start nonblocking host name lookup */
net_gethostbyname_nonblock(server, rec->pipes[1], 0);
net_gethostbyname_nonblock(server, rec->pipes[1], 0, 0);
rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ,
(GInputFunction) simple_readpipe, rec);

View file

@ -26,7 +26,7 @@ typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *);
/* nonblocking gethostbyname(), PID of the resolver child is returned. */
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
int reverse_lookup);
int family, int reverse_lookup);
/* 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 occurred with read() */

View file

@ -141,7 +141,8 @@ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip)
g_return_val_if_fail(addr != NULL, NULL);
if (net_gethostbyname(addr, &ip) == -1)
// XXX : should we use the my_ip->family instead ?
if (net_gethostbyname(addr, &ip, 0) == -1)
return NULL;
return net_connect_ip(&ip, port, my_ip);
@ -392,9 +393,9 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
If ip->family is 0, the address wasn't found.
Returns 0 = ok, others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip)
int net_gethostbyname(const char *addr, IPADDR *ip, int family)
{
union sockaddr_union *so;
const union sockaddr_union *so;
struct addrinfo hints, *ailist;
int ret;
@ -405,7 +406,7 @@ int net_gethostbyname(const char *addr, IPADDR *ip)
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_socktype = SOCK_STREAM;
#ifdef HAVE_IPV6
hints.ai_family = AF_UNSPEC;
hints.ai_family = (family == 0) ? AF_UNSPEC : family;
#else
hints.ai_family = AF_INET;
#endif

View file

@ -71,7 +71,7 @@ int net_transmit(GIOChannel *handle, const char *data, int len);
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
If ip->family is 0, the address wasn't found.
Returns 0 = ok, others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip);
int net_gethostbyname(const char *addr, IPADDR *ip, int family);
/* 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);

View file

@ -56,7 +56,7 @@ static void get_source_host_ip(void)
/* FIXME: This will block! */
hostname = settings_get_str("hostname");
source_host_ok = *hostname != '\0' &&
net_gethostbyname(hostname, &source_host_ip) == 0;
net_gethostbyname(hostname, &source_host_ip, 0) == 0;
}
static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
@ -66,7 +66,7 @@ static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
if (*own_ip == NULL) {
/* resolve the IP */
if (net_gethostbyname(own_host, &ip) == 0)
if (net_gethostbyname(own_host, &ip, 0) == 0)
save_ips(&ip, own_ip);
}

View file

@ -283,13 +283,15 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
ip = NULL;
if (iprec.error == 0) {
// FIXME : REMOVE THIS BEFORE MERGE
if (server->connrec->family)
g_assert(server->connrec->family == iprec.ip.family);
/* we've resolved the server address, now check whether the version
* of the one returned by the system matches the one required by the
* user by using -{4,6} or by specifying the "family" parameter for
* the server */
if (server->connrec->family == 0 || server->connrec->family == iprec.ip.family) {
ip = &iprec.ip;
servername = iprec.host;
}
}
if (ip != NULL) {
/* host lookup ok */
@ -407,6 +409,7 @@ int server_start_connect(SERVER_REC *server)
server->connect_pid =
net_gethostbyname_nonblock(connect_address,
server->connect_pipe[1],
server->connrec->family,
settings_get_bool("resolve_reverse_lookup"));
server->connect_tag =
g_input_add(server->connect_pipe[0], G_INPUT_READ,

View file

@ -593,7 +593,7 @@ static void add_listen(const char *ircnet, int port)
/* bind to specific host/ip? */
my_ip = NULL;
if (*settings_get_str("irssiproxy_bind") != '\0') {
if (net_gethostbyname(settings_get_str("irssiproxy_bind"), &ip) != 0) {
if (net_gethostbyname(settings_get_str("irssiproxy_bind"), &ip, 0) != 0) {
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
"Proxy: can not resolve '%s' - aborting",
settings_get_str("irssiproxy_bind"));