mirror of
https://github.com/irssi/irssi.git
synced 2024-09-08 04:26:01 -04:00
Merge pull request #296 from irssi/revert-290-ipv6
Revert "Network and IPv{4,6} related changes" it wasn't ready yet and I merged this in error
This commit is contained in:
commit
f32620673e
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
%9Examples:%9
|
%9Examples:%9
|
||||||
|
|
||||||
/TOGGLE resolve_reverse_lookup
|
/TOGGLE resolve_prefer_ipv6
|
||||||
/TOGGLE channels_rejoin_unavailable ON
|
/TOGGLE channels_rejoin_unavailable ON
|
||||||
|
|
||||||
%9See also:%9 SET
|
%9See also:%9 SET
|
||||||
|
@ -429,6 +429,9 @@
|
|||||||
After connected to server, Irssi can automatically change your user
|
After connected to server, Irssi can automatically change your user
|
||||||
mode. You can set it with /SET usermode <mode>, default is +i.
|
mode. You can set it with /SET usermode <mode>, default is +i.
|
||||||
|
|
||||||
|
/SET resolve_prefer_ipv6 - If ON, prefer IPv6 for hosts that
|
||||||
|
have both v4 and v6 addresses.
|
||||||
|
|
||||||
5.5 Automatic reconnecting
|
5.5 Automatic reconnecting
|
||||||
|
|
||||||
If you get disconnected from server, Irssi will try to reconnect
|
If you get disconnected from server, Irssi will try to reconnect
|
||||||
|
@ -128,10 +128,10 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
|
|||||||
|
|
||||||
host = g_hash_table_lookup(optlist, "host");
|
host = g_hash_table_lookup(optlist, "host");
|
||||||
if (host != NULL && *host != '\0') {
|
if (host != NULL && *host != '\0') {
|
||||||
IPADDR ip;
|
IPADDR ip4, ip6;
|
||||||
|
|
||||||
if (net_gethostbyname(host, &ip) == 0)
|
if (net_gethostbyname(host, &ip4, &ip6) == 0)
|
||||||
server_connect_own_ip_save(conn, &ip);
|
server_connect_own_ip_save(conn, &ip4, &ip6);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
|
@ -9,4 +9,4 @@ char *realname;
|
|||||||
|
|
||||||
char *own_host; /* address to use when connecting this server */
|
char *own_host; /* address to use when connecting this server */
|
||||||
char *autosendcmd; /* command to send after connecting to this ircnet */
|
char *autosendcmd; /* command to send after connecting to this ircnet */
|
||||||
IPADDR *own_ip; /* resolved own_address if not NULL */
|
IPADDR *own_ip4, *own_ip6; /* resolved own_address if not NULL */
|
||||||
|
@ -103,12 +103,15 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
|
|||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
memset(&rec, 0, sizeof(rec));
|
memset(&rec, 0, sizeof(rec));
|
||||||
rec.error = net_gethostbyname(addr, &rec.ip);
|
rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6);
|
||||||
if (rec.error == 0) {
|
if (rec.error == 0) {
|
||||||
errorstr = NULL;
|
errorstr = NULL;
|
||||||
if (reverse_lookup) {
|
if (reverse_lookup) {
|
||||||
/* reverse lookup the IP, ignore any error */
|
/* reverse lookup the IP, ignore any error */
|
||||||
net_gethostbyaddr(&rec.ip, &rec.host);
|
if (rec.ip4.family != 0)
|
||||||
|
net_gethostbyaddr(&rec.ip4, &rec.host4);
|
||||||
|
if (rec.ip6.family != 0)
|
||||||
|
net_gethostbyaddr(&rec.ip6, &rec.host6);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errorstr = net_gethosterror(rec.error);
|
errorstr = net_gethosterror(rec.error);
|
||||||
@ -119,11 +122,18 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe,
|
|||||||
if (rec.errlen != 0)
|
if (rec.errlen != 0)
|
||||||
g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
|
g_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
|
||||||
else {
|
else {
|
||||||
if (rec.host) {
|
if (rec.host4) {
|
||||||
len = strlen(rec.host) + 1;
|
len = strlen(rec.host4) + 1;
|
||||||
g_io_channel_write_block(pipe, (void *) &len,
|
g_io_channel_write_block(pipe, (void *) &len,
|
||||||
sizeof(int));
|
sizeof(int));
|
||||||
g_io_channel_write_block(pipe, (void *) rec.host,
|
g_io_channel_write_block(pipe, (void *) rec.host4,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
if (rec.host6) {
|
||||||
|
len = strlen(rec.host6) + 1;
|
||||||
|
g_io_channel_write_block(pipe, (void *) &len,
|
||||||
|
sizeof(int));
|
||||||
|
g_io_channel_write_block(pipe, (void *) rec.host6,
|
||||||
len);
|
len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +154,8 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
|
|||||||
|
|
||||||
rec->error = -1;
|
rec->error = -1;
|
||||||
rec->errorstr = NULL;
|
rec->errorstr = NULL;
|
||||||
rec->host = NULL;
|
rec->host4 = NULL;
|
||||||
|
rec->host6 = NULL;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
|
fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
|
||||||
@ -163,10 +174,15 @@ int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
|
|||||||
rec->errorstr = g_malloc0(rec->errlen+1);
|
rec->errorstr = g_malloc0(rec->errlen+1);
|
||||||
g_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
|
g_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
|
||||||
} else {
|
} else {
|
||||||
if (rec->host) {
|
if (rec->host4) {
|
||||||
g_io_channel_read_block(pipe, &len, sizeof(int));
|
g_io_channel_read_block(pipe, &len, sizeof(int));
|
||||||
rec->host = g_malloc0(len);
|
rec->host4 = g_malloc0(len);
|
||||||
g_io_channel_read_block(pipe, rec->host, len);
|
g_io_channel_read_block(pipe, rec->host4, len);
|
||||||
|
}
|
||||||
|
if (rec->host6) {
|
||||||
|
g_io_channel_read_block(pipe, &len, sizeof(int));
|
||||||
|
rec->host6 = g_malloc0(len);
|
||||||
|
g_io_channel_read_block(pipe, rec->host6, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +227,7 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe)
|
|||||||
{
|
{
|
||||||
RESOLVED_IP_REC iprec;
|
RESOLVED_IP_REC iprec;
|
||||||
GIOChannel *handle;
|
GIOChannel *handle;
|
||||||
|
IPADDR *ip;
|
||||||
|
|
||||||
g_return_if_fail(rec != NULL);
|
g_return_if_fail(rec != NULL);
|
||||||
|
|
||||||
@ -224,8 +241,9 @@ static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe)
|
|||||||
g_io_channel_shutdown(rec->pipes[1], TRUE, NULL);
|
g_io_channel_shutdown(rec->pipes[1], TRUE, NULL);
|
||||||
g_io_channel_unref(rec->pipes[1]);
|
g_io_channel_unref(rec->pipes[1]);
|
||||||
|
|
||||||
|
ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6;
|
||||||
handle = iprec.error == -1 ? NULL :
|
handle = iprec.error == -1 ? NULL :
|
||||||
net_connect_ip(&iprec.ip, rec->port, rec->my_ip);
|
net_connect_ip(ip, rec->port, rec->my_ip);
|
||||||
|
|
||||||
g_free_not_null(rec->my_ip);
|
g_free_not_null(rec->my_ip);
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IPADDR ip; /* resolved ip address */
|
IPADDR ip4, ip6; /* resolved ip addresses */
|
||||||
int error; /* error, 0 = no error, -1 = error: */
|
int error; /* error, 0 = no error, -1 = error: */
|
||||||
int errlen; /* error text length */
|
int errlen; /* error text length */
|
||||||
char *errorstr; /* error string - dynamically allocated, you'll
|
char *errorstr; /* error string - dynamically allocated, you'll
|
||||||
need to free() it yourself unless it's NULL */
|
need to free() it yourself unless it's NULL */
|
||||||
char *host; /* dito */
|
char *host4, *host6; /* dito */
|
||||||
} RESOLVED_IP_REC;
|
} RESOLVED_IP_REC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -137,14 +137,35 @@ static int sin_get_port(union sockaddr_union *so)
|
|||||||
/* Connect to socket */
|
/* Connect to socket */
|
||||||
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip)
|
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip)
|
||||||
{
|
{
|
||||||
IPADDR ip;
|
IPADDR ip4, ip6, *ip;
|
||||||
|
|
||||||
g_return_val_if_fail(addr != NULL, NULL);
|
g_return_val_if_fail(addr != NULL, NULL);
|
||||||
|
|
||||||
if (net_gethostbyname(addr, &ip) == -1)
|
if (net_gethostbyname(addr, &ip4, &ip6) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return net_connect_ip(&ip, port, my_ip);
|
if (my_ip == NULL) {
|
||||||
|
/* prefer IPv4 addresses */
|
||||||
|
ip = ip4.family != 0 ? &ip4 : &ip6;
|
||||||
|
} else if (IPADDR_IS_V6(my_ip)) {
|
||||||
|
/* my_ip is IPv6 address, use it if possible */
|
||||||
|
if (ip6.family != 0)
|
||||||
|
ip = &ip6;
|
||||||
|
else {
|
||||||
|
my_ip = NULL;
|
||||||
|
ip = &ip4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* my_ip is IPv4 address, use it if possible */
|
||||||
|
if (ip4.family != 0)
|
||||||
|
ip = &ip4;
|
||||||
|
else {
|
||||||
|
my_ip = NULL;
|
||||||
|
ip = &ip6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return net_connect_ip(ip, port, my_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to socket with ip address */
|
/* Connect to socket with ip address */
|
||||||
@ -392,35 +413,82 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
|
|||||||
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
|
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
|
||||||
If ip->family is 0, the address wasn't found.
|
If ip->family is 0, the address wasn't found.
|
||||||
Returns 0 = ok, others = error code for net_gethosterror() */
|
Returns 0 = ok, others = error code for net_gethosterror() */
|
||||||
int net_gethostbyname(const char *addr, IPADDR *ip)
|
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
union sockaddr_union *so;
|
union sockaddr_union *so;
|
||||||
struct addrinfo hints, *ailist;
|
struct addrinfo hints, *ai, *ailist;
|
||||||
int ret;
|
int ret, count_v4, count_v6, use_v4, use_v6;
|
||||||
|
#else
|
||||||
|
struct hostent *hp;
|
||||||
|
int count;
|
||||||
|
#endif
|
||||||
|
|
||||||
g_return_val_if_fail(addr != NULL, -1);
|
g_return_val_if_fail(addr != NULL, -1);
|
||||||
|
|
||||||
memset(ip, 0, sizeof(IPADDR));
|
memset(ip4, 0, sizeof(IPADDR));
|
||||||
|
memset(ip6, 0, sizeof(IPADDR));
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
|
||||||
#else
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
#endif
|
|
||||||
hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
|
|
||||||
|
|
||||||
/* save error to host_error for later use */
|
/* save error to host_error for later use */
|
||||||
ret = getaddrinfo(addr, NULL, &hints, &ailist);
|
ret = getaddrinfo(addr, NULL, &hints, &ailist);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
so = (const union sockaddr_union *)ailist->ai_addr;
|
/* count IPs */
|
||||||
sin_get_ip(so, ip);
|
count_v4 = count_v6 = 0;
|
||||||
|
for (ai = ailist; ai != NULL; ai = ai->ai_next) {
|
||||||
|
if (ai->ai_family == AF_INET)
|
||||||
|
count_v4++;
|
||||||
|
else if (ai->ai_family == AF_INET6)
|
||||||
|
count_v6++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count_v4 == 0 && count_v6 == 0)
|
||||||
|
return HOST_NOT_FOUND; /* shouldn't happen? */
|
||||||
|
|
||||||
|
/* if there are multiple addresses, return random one */
|
||||||
|
use_v4 = count_v4 <= 1 ? 0 : rand() % count_v4;
|
||||||
|
use_v6 = count_v6 <= 1 ? 0 : rand() % count_v6;
|
||||||
|
|
||||||
|
count_v4 = count_v6 = 0;
|
||||||
|
for (ai = ailist; ai != NULL; ai = ai->ai_next) {
|
||||||
|
so = (union sockaddr_union *) ai->ai_addr;
|
||||||
|
|
||||||
|
if (ai->ai_family == AF_INET) {
|
||||||
|
if (use_v4 == count_v4)
|
||||||
|
sin_get_ip(so, ip4);
|
||||||
|
count_v4++;
|
||||||
|
} else if (ai->ai_family == AF_INET6) {
|
||||||
|
if (use_v6 == count_v6)
|
||||||
|
sin_get_ip(so, ip6);
|
||||||
|
count_v6++;
|
||||||
|
}
|
||||||
|
}
|
||||||
freeaddrinfo(ailist);
|
freeaddrinfo(ailist);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
hp = gethostbyname(addr);
|
||||||
|
if (hp == NULL)
|
||||||
|
return h_errno;
|
||||||
|
|
||||||
|
/* count IPs */
|
||||||
|
count = 0;
|
||||||
|
while (hp->h_addr_list[count] != NULL)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return HOST_NOT_FOUND; /* shouldn't happen? */
|
||||||
|
|
||||||
|
/* if there are multiple addresses, return random one */
|
||||||
|
ip4->family = AF_INET;
|
||||||
|
memcpy(&ip4->ip, hp->h_addr_list[rand() % count], 4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get name for host, *name should be g_free()'d unless it's NULL.
|
/* Get name for host, *name should be g_free()'d unless it's NULL.
|
||||||
|
@ -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.
|
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
|
||||||
If ip->family is 0, the address wasn't found.
|
If ip->family is 0, the address wasn't found.
|
||||||
Returns 0 = ok, others = error code for net_gethosterror() */
|
Returns 0 = ok, others = error code for net_gethosterror() */
|
||||||
int net_gethostbyname(const char *addr, IPADDR *ip);
|
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6);
|
||||||
/* Get name for host, *name should be g_free()'d unless it's NULL.
|
/* Get name for host, *name should be g_free()'d unless it's NULL.
|
||||||
Return values are the same as with net_gethostbyname() */
|
Return values are the same as with net_gethostbyname() */
|
||||||
int net_gethostbyaddr(IPADDR *ip, char **name);
|
int net_gethostbyaddr(IPADDR *ip, char **name);
|
||||||
|
@ -16,7 +16,7 @@ char *address;
|
|||||||
int port;
|
int port;
|
||||||
char *chatnet;
|
char *chatnet;
|
||||||
|
|
||||||
IPADDR *own_ip;
|
IPADDR *own_ip4, *own_ip6;
|
||||||
|
|
||||||
char *password;
|
char *password;
|
||||||
char *nick;
|
char *nick;
|
||||||
|
@ -19,7 +19,7 @@ char *ssl_capath;
|
|||||||
char *ssl_ciphers;
|
char *ssl_ciphers;
|
||||||
|
|
||||||
char *own_host; /* address to use when connecting this server */
|
char *own_host; /* address to use when connecting this server */
|
||||||
IPADDR *own_ip; /* resolved own_address if not NULL */
|
IPADDR *own_ip4, *own_ip6; /* resolved own_address if not NULL */
|
||||||
|
|
||||||
time_t last_connect; /* to avoid reconnecting too fast.. */
|
time_t last_connect; /* to avoid reconnecting too fast.. */
|
||||||
|
|
||||||
|
@ -177,9 +177,13 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
|
|||||||
dest->username = g_strdup(src->username);
|
dest->username = g_strdup(src->username);
|
||||||
dest->realname = g_strdup(src->realname);
|
dest->realname = g_strdup(src->realname);
|
||||||
|
|
||||||
if (src->own_ip != NULL) {
|
if (src->own_ip4 != NULL) {
|
||||||
dest->own_ip = g_new(IPADDR, 1);
|
dest->own_ip4 = g_new(IPADDR, 1);
|
||||||
memcpy(dest->own_ip, src->own_ip, sizeof(IPADDR));
|
memcpy(dest->own_ip4, src->own_ip4, sizeof(IPADDR));
|
||||||
|
}
|
||||||
|
if (src->own_ip6 != NULL) {
|
||||||
|
dest->own_ip6 = g_new(IPADDR, 1);
|
||||||
|
memcpy(dest->own_ip6, src->own_ip6, sizeof(IPADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
dest->channels = g_strdup(src->channels);
|
dest->channels = g_strdup(src->channels);
|
||||||
|
@ -33,22 +33,32 @@ GSList *setupservers;
|
|||||||
|
|
||||||
static char *old_source_host;
|
static char *old_source_host;
|
||||||
int source_host_ok; /* Use source_host_ip .. */
|
int source_host_ok; /* Use source_host_ip .. */
|
||||||
IPADDR source_host_ip; /* Resolved address */
|
IPADDR *source_host_ip4, *source_host_ip6; /* Resolved address */
|
||||||
|
|
||||||
static void save_ips(IPADDR *ip, IPADDR **save_ip)
|
static void save_ips(IPADDR *ip4, IPADDR *ip6,
|
||||||
|
IPADDR **save_ip4, IPADDR **save_ip6)
|
||||||
{
|
{
|
||||||
if (ip->family == 0)
|
if (ip4->family == 0)
|
||||||
g_free_and_null(*save_ip);
|
g_free_and_null(*save_ip4);
|
||||||
else {
|
else {
|
||||||
if (*save_ip == NULL)
|
if (*save_ip4 == NULL)
|
||||||
*save_ip = g_new(IPADDR, 1);
|
*save_ip4 = g_new(IPADDR, 1);
|
||||||
memcpy(*save_ip, ip, sizeof(IPADDR));
|
memcpy(*save_ip4, ip4, sizeof(IPADDR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip6->family == 0)
|
||||||
|
g_free_and_null(*save_ip6);
|
||||||
|
else {
|
||||||
|
if (*save_ip6 == NULL)
|
||||||
|
*save_ip6 = g_new(IPADDR, 1);
|
||||||
|
memcpy(*save_ip6, ip6, sizeof(IPADDR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_source_host_ip(void)
|
static void get_source_host_ip(void)
|
||||||
{
|
{
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
|
IPADDR ip4, ip6;
|
||||||
|
|
||||||
if (source_host_ok)
|
if (source_host_ok)
|
||||||
return;
|
return;
|
||||||
@ -56,21 +66,28 @@ static void get_source_host_ip(void)
|
|||||||
/* FIXME: This will block! */
|
/* FIXME: This will block! */
|
||||||
hostname = settings_get_str("hostname");
|
hostname = settings_get_str("hostname");
|
||||||
source_host_ok = *hostname != '\0' &&
|
source_host_ok = *hostname != '\0' &&
|
||||||
net_gethostbyname(hostname, &source_host_ip) == 0;
|
net_gethostbyname(hostname, &ip4, &ip6) == 0;
|
||||||
|
|
||||||
|
if (source_host_ok)
|
||||||
|
save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6);
|
||||||
|
else {
|
||||||
|
g_free_and_null(source_host_ip4);
|
||||||
|
g_free_and_null(source_host_ip6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
|
static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
|
||||||
IPADDR **own_ip)
|
IPADDR **own_ip4, IPADDR **own_ip6)
|
||||||
{
|
{
|
||||||
IPADDR ip;
|
IPADDR ip4, ip6;
|
||||||
|
|
||||||
if (*own_ip == NULL) {
|
if (*own_ip4 == NULL && *own_ip6 == NULL) {
|
||||||
/* resolve the IP */
|
/* resolve the IP */
|
||||||
if (net_gethostbyname(own_host, &ip) == 0)
|
if (net_gethostbyname(own_host, &ip4, &ip6) == 0)
|
||||||
save_ips(&ip, own_ip);
|
save_ips(&ip4, &ip6, own_ip4, own_ip6);
|
||||||
}
|
}
|
||||||
|
|
||||||
server_connect_own_ip_save(conn, *own_ip);
|
server_connect_own_ip_save(conn, *own_ip4, *own_ip6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill information to connection from server setup record */
|
/* Fill information to connection from server setup record */
|
||||||
@ -81,7 +98,8 @@ void server_setup_fill_reconn(SERVER_CONNECT_REC *conn,
|
|||||||
g_return_if_fail(IS_SERVER_SETUP(sserver));
|
g_return_if_fail(IS_SERVER_SETUP(sserver));
|
||||||
|
|
||||||
if (sserver->own_host != NULL) {
|
if (sserver->own_host != NULL) {
|
||||||
conn_set_ip(conn, sserver->own_host, &sserver->own_ip);
|
conn_set_ip(conn, sserver->own_host,
|
||||||
|
&sserver->own_ip4, &sserver->own_ip6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sserver->chatnet != NULL && conn->chatnet == NULL)
|
if (sserver->chatnet != NULL && conn->chatnet == NULL)
|
||||||
@ -121,9 +139,13 @@ static void server_setup_fill(SERVER_CONNECT_REC *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* source IP */
|
/* source IP */
|
||||||
if (source_host_ok) {
|
if (source_host_ip4 != NULL) {
|
||||||
conn->own_ip = g_new(IPADDR, 1);
|
conn->own_ip4 = g_new(IPADDR, 1);
|
||||||
memcpy(conn->own_ip, &source_host_ip, sizeof(IPADDR));
|
memcpy(conn->own_ip4, source_host_ip4, sizeof(IPADDR));
|
||||||
|
}
|
||||||
|
if (source_host_ip6 != NULL) {
|
||||||
|
conn->own_ip6 = g_new(IPADDR, 1);
|
||||||
|
memcpy(conn->own_ip6, source_host_ip6, sizeof(IPADDR));
|
||||||
}
|
}
|
||||||
|
|
||||||
signal_emit("server setup fill connect", 1, conn);
|
signal_emit("server setup fill connect", 1, conn);
|
||||||
@ -184,7 +206,8 @@ static void server_setup_fill_chatnet(SERVER_CONNECT_REC *conn,
|
|||||||
conn->realname = g_strdup(chatnet->realname);;
|
conn->realname = g_strdup(chatnet->realname);;
|
||||||
}
|
}
|
||||||
if (chatnet->own_host != NULL) {
|
if (chatnet->own_host != NULL) {
|
||||||
conn_set_ip(conn, chatnet->own_host, &chatnet->own_ip);
|
conn_set_ip(conn, chatnet->own_host,
|
||||||
|
&chatnet->own_ip4, &chatnet->own_ip6);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal_emit("server setup fill chatnet", 2, conn, chatnet);
|
signal_emit("server setup fill chatnet", 2, conn, chatnet);
|
||||||
@ -458,7 +481,8 @@ static void server_setup_destroy(SERVER_SETUP_REC *rec)
|
|||||||
signal_emit("server setup destroyed", 1, rec);
|
signal_emit("server setup destroyed", 1, rec);
|
||||||
|
|
||||||
g_free_not_null(rec->own_host);
|
g_free_not_null(rec->own_host);
|
||||||
g_free_not_null(rec->own_ip);
|
g_free_not_null(rec->own_ip4);
|
||||||
|
g_free_not_null(rec->own_ip6);
|
||||||
g_free_not_null(rec->chatnet);
|
g_free_not_null(rec->chatnet);
|
||||||
g_free_not_null(rec->password);
|
g_free_not_null(rec->password);
|
||||||
g_free_not_null(rec->ssl_cert);
|
g_free_not_null(rec->ssl_cert);
|
||||||
@ -532,6 +556,7 @@ void servers_setup_init(void)
|
|||||||
settings_add_str("proxy", "proxy_password", "");
|
settings_add_str("proxy", "proxy_password", "");
|
||||||
|
|
||||||
setupservers = NULL;
|
setupservers = NULL;
|
||||||
|
source_host_ip4 = source_host_ip6 = NULL;
|
||||||
old_source_host = NULL;
|
old_source_host = NULL;
|
||||||
read_settings();
|
read_settings();
|
||||||
|
|
||||||
@ -542,6 +567,8 @@ void servers_setup_init(void)
|
|||||||
|
|
||||||
void servers_setup_deinit(void)
|
void servers_setup_deinit(void)
|
||||||
{
|
{
|
||||||
|
g_free_not_null(source_host_ip4);
|
||||||
|
g_free_not_null(source_host_ip6);
|
||||||
g_free_not_null(old_source_host);
|
g_free_not_null(old_source_host);
|
||||||
|
|
||||||
while (setupservers != NULL)
|
while (setupservers != NULL)
|
||||||
|
@ -16,7 +16,7 @@ struct _SERVER_SETUP_REC {
|
|||||||
|
|
||||||
extern GSList *setupservers;
|
extern GSList *setupservers;
|
||||||
|
|
||||||
extern IPADDR source_host_ip; /* Resolved address */
|
extern IPADDR *source_host_ip4, *source_host_ip6; /* Resolved address */
|
||||||
extern int source_host_ok; /* Use source_host_ip .. */
|
extern int source_host_ok; /* Use source_host_ip .. */
|
||||||
|
|
||||||
/* Fill reconnection specific information to connection
|
/* Fill reconnection specific information to connection
|
||||||
|
@ -218,7 +218,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (ip != NULL) {
|
if (ip != NULL) {
|
||||||
own_ip = server->connrec->own_ip;
|
own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
|
||||||
port = server->connrec->proxy != NULL ?
|
port = server->connrec->proxy != NULL ?
|
||||||
server->connrec->proxy_port : server->connrec->port;
|
server->connrec->proxy_port : server->connrec->port;
|
||||||
handle = server->connrec->use_ssl ?
|
handle = server->connrec->use_ssl ?
|
||||||
@ -280,15 +280,30 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
|
|||||||
server->connect_pipe[0] = NULL;
|
server->connect_pipe[0] = NULL;
|
||||||
server->connect_pipe[1] = NULL;
|
server->connect_pipe[1] = NULL;
|
||||||
|
|
||||||
ip = NULL;
|
/* figure out if we should use IPv4 or v6 address */
|
||||||
|
if (iprec.error != 0) {
|
||||||
if (iprec.error == 0) {
|
/* error */
|
||||||
// FIXME : REMOVE THIS BEFORE MERGE
|
ip = NULL;
|
||||||
if (server->connrec->family)
|
} else if (server->connrec->family == AF_INET) {
|
||||||
g_assert(server->connrec->family == iprec.ip.family);
|
/* force IPv4 connection */
|
||||||
|
ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4;
|
||||||
ip = &iprec.ip;
|
servername = iprec.host4;
|
||||||
servername = iprec.host;
|
} else if (server->connrec->family == AF_INET6) {
|
||||||
|
/* force IPv6 connection */
|
||||||
|
ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6;
|
||||||
|
servername = iprec.host6;
|
||||||
|
} else {
|
||||||
|
/* pick the one that was found, or if both do it like
|
||||||
|
/SET resolve_prefer_ipv6 says. */
|
||||||
|
if (iprec.ip4.family == 0 ||
|
||||||
|
(iprec.ip6.family != 0 &&
|
||||||
|
settings_get_bool("resolve_prefer_ipv6"))) {
|
||||||
|
ip = &iprec.ip6;
|
||||||
|
servername = iprec.host6;
|
||||||
|
} else {
|
||||||
|
ip = &iprec.ip4;
|
||||||
|
servername = iprec.host4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip != NULL) {
|
if (ip != NULL) {
|
||||||
@ -322,7 +337,8 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_free(iprec.errorstr);
|
g_free(iprec.errorstr);
|
||||||
g_free(iprec.host);
|
g_free(iprec.host4);
|
||||||
|
g_free(iprec.host6);
|
||||||
}
|
}
|
||||||
|
|
||||||
SERVER_REC *server_connect(SERVER_CONNECT_REC *conn)
|
SERVER_REC *server_connect(SERVER_CONNECT_REC *conn)
|
||||||
@ -607,7 +623,8 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
|
|||||||
g_free_not_null(conn->address);
|
g_free_not_null(conn->address);
|
||||||
g_free_not_null(conn->chatnet);
|
g_free_not_null(conn->chatnet);
|
||||||
|
|
||||||
g_free_not_null(conn->own_ip);
|
g_free_not_null(conn->own_ip4);
|
||||||
|
g_free_not_null(conn->own_ip6);
|
||||||
|
|
||||||
g_free_not_null(conn->password);
|
g_free_not_null(conn->password);
|
||||||
g_free_not_null(conn->nick);
|
g_free_not_null(conn->nick);
|
||||||
@ -637,15 +654,26 @@ void server_change_nick(SERVER_REC *server, const char *nick)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update own IPv4 and IPv6 records */
|
/* Update own IPv4 and IPv6 records */
|
||||||
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn, IPADDR *ip)
|
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn,
|
||||||
|
IPADDR *ip4, IPADDR *ip6)
|
||||||
{
|
{
|
||||||
if (ip == NULL || ip->family == 0)
|
if (ip4 == NULL || ip4->family == 0)
|
||||||
g_free_and_null(conn->own_ip);
|
g_free_and_null(conn->own_ip4);
|
||||||
|
if (ip6 == NULL || ip6->family == 0)
|
||||||
|
g_free_and_null(conn->own_ip6);
|
||||||
|
|
||||||
if (ip != NULL && ip->family != 0) {
|
if (ip4 != NULL && ip4->family != 0) {
|
||||||
if (conn->own_ip == NULL)
|
/* IPv4 address was found */
|
||||||
conn->own_ip = g_new0(IPADDR, 1);
|
if (conn->own_ip4 == NULL)
|
||||||
memcpy(conn->own_ip, ip, sizeof(IPADDR));
|
conn->own_ip4 = g_new0(IPADDR, 1);
|
||||||
|
memcpy(conn->own_ip4, ip4, sizeof(IPADDR));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip6 != NULL && ip6->family != 0) {
|
||||||
|
/* IPv6 address was found */
|
||||||
|
if (conn->own_ip6 == NULL)
|
||||||
|
conn->own_ip6 = g_new0(IPADDR, 1);
|
||||||
|
memcpy(conn->own_ip6, ip6, sizeof(IPADDR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,6 +738,7 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto)
|
|||||||
|
|
||||||
void servers_init(void)
|
void servers_init(void)
|
||||||
{
|
{
|
||||||
|
settings_add_bool("server", "resolve_prefer_ipv6", FALSE);
|
||||||
settings_add_bool("server", "resolve_reverse_lookup", FALSE);
|
settings_add_bool("server", "resolve_reverse_lookup", FALSE);
|
||||||
lookup_servers = servers = NULL;
|
lookup_servers = servers = NULL;
|
||||||
|
|
||||||
|
@ -67,7 +67,8 @@ void server_connect_failed(SERVER_REC *server, const char *msg);
|
|||||||
void server_change_nick(SERVER_REC *server, const char *nick);
|
void server_change_nick(SERVER_REC *server, const char *nick);
|
||||||
|
|
||||||
/* Update own IPv4 and IPv6 records */
|
/* Update own IPv4 and IPv6 records */
|
||||||
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn, IPADDR *ip);
|
void server_connect_own_ip_save(SERVER_CONNECT_REC *conn,
|
||||||
|
IPADDR *ip4, IPADDR *ip6);
|
||||||
|
|
||||||
/* `optlist' should contain only one unknown key - the server tag.
|
/* `optlist' should contain only one unknown key - the server tag.
|
||||||
returns NULL if there was unknown -option */
|
returns NULL if there was unknown -option */
|
||||||
|
@ -138,7 +138,7 @@ static void cmd_server_add(const char *data)
|
|||||||
if (*password != '\0') g_free_and_null(rec->password);
|
if (*password != '\0') g_free_and_null(rec->password);
|
||||||
if (g_hash_table_lookup(optlist, "host")) {
|
if (g_hash_table_lookup(optlist, "host")) {
|
||||||
g_free_and_null(rec->own_host);
|
g_free_and_null(rec->own_host);
|
||||||
rec->own_ip = NULL;
|
rec->own_ip4 = rec->own_ip6 = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ static void cmd_server_add(const char *data)
|
|||||||
value = g_hash_table_lookup(optlist, "host");
|
value = g_hash_table_lookup(optlist, "host");
|
||||||
if (value != NULL && *value != '\0') {
|
if (value != NULL && *value != '\0') {
|
||||||
rec->own_host = g_strdup(value);
|
rec->own_host = g_strdup(value);
|
||||||
rec->own_ip = NULL;
|
rec->own_ip4 = rec->own_ip6 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal_emit("server add fill", 2, rec, optlist);
|
signal_emit("server add fill", 2, rec, optlist);
|
||||||
|
@ -108,7 +108,7 @@ static void cmd_network_add(const char *data)
|
|||||||
if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname);
|
if (g_hash_table_lookup(optlist, "realname")) g_free_and_null(rec->realname);
|
||||||
if (g_hash_table_lookup(optlist, "host")) {
|
if (g_hash_table_lookup(optlist, "host")) {
|
||||||
g_free_and_null(rec->own_host);
|
g_free_and_null(rec->own_host);
|
||||||
rec->own_ip = NULL;
|
rec->own_ip4 = rec->own_ip6 = NULL;
|
||||||
}
|
}
|
||||||
if (g_hash_table_lookup(optlist, "usermode")) g_free_and_null(rec->usermode);
|
if (g_hash_table_lookup(optlist, "usermode")) g_free_and_null(rec->usermode);
|
||||||
if (g_hash_table_lookup(optlist, "autosendcmd")) g_free_and_null(rec->autosendcmd);
|
if (g_hash_table_lookup(optlist, "autosendcmd")) g_free_and_null(rec->autosendcmd);
|
||||||
@ -140,7 +140,7 @@ static void cmd_network_add(const char *data)
|
|||||||
value = g_hash_table_lookup(optlist, "host");
|
value = g_hash_table_lookup(optlist, "host");
|
||||||
if (value != NULL && *value != '\0') {
|
if (value != NULL && *value != '\0') {
|
||||||
rec->own_host = g_strdup(value);
|
rec->own_host = g_strdup(value);
|
||||||
rec->own_ip = NULL;
|
rec->own_ip4 = rec->own_ip6 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = g_hash_table_lookup(optlist, "usermode");
|
value = g_hash_table_lookup(optlist, "usermode");
|
||||||
|
@ -264,12 +264,12 @@ GIOChannel *dcc_connect_ip(IPADDR *ip, int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (own_ip == NULL)
|
if (own_ip == NULL)
|
||||||
own_ip = &source_host_ip;
|
own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4;
|
||||||
|
|
||||||
handle = net_connect_ip(ip, port, own_ip);
|
handle = net_connect_ip(ip, port, own_ip);
|
||||||
if (handle == NULL && errno == EADDRNOTAVAIL && own_ip != NULL) {
|
if (handle == NULL && errno == EADDRNOTAVAIL && own_ip != NULL) {
|
||||||
/* dcc_own_ip is external address */
|
/* dcc_own_ip is external address */
|
||||||
own_ip = &source_host_ip;
|
own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4;
|
||||||
handle = net_connect_ip(ip, port, own_ip);
|
handle = net_connect_ip(ip, port, own_ip);
|
||||||
}
|
}
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -585,7 +585,7 @@ static LISTEN_REC *find_listen(const char *ircnet, int port)
|
|||||||
static void add_listen(const char *ircnet, int port)
|
static void add_listen(const char *ircnet, int port)
|
||||||
{
|
{
|
||||||
LISTEN_REC *rec;
|
LISTEN_REC *rec;
|
||||||
IPADDR ip, *my_ip;
|
IPADDR ip4, ip6, *my_ip;
|
||||||
|
|
||||||
if (port <= 0 || *ircnet == '\0')
|
if (port <= 0 || *ircnet == '\0')
|
||||||
return;
|
return;
|
||||||
@ -593,13 +593,16 @@ static void add_listen(const char *ircnet, int port)
|
|||||||
/* bind to specific host/ip? */
|
/* bind to specific host/ip? */
|
||||||
my_ip = NULL;
|
my_ip = NULL;
|
||||||
if (*settings_get_str("irssiproxy_bind") != '\0') {
|
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"),
|
||||||
|
&ip4, &ip6) != 0) {
|
||||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
|
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
|
||||||
"Proxy: can not resolve '%s' - aborting",
|
"Proxy: can not resolve '%s' - aborting",
|
||||||
settings_get_str("irssiproxy_bind"));
|
settings_get_str("irssiproxy_bind"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my_ip = &ip;
|
|
||||||
|
my_ip = ip6.family == 0 ? &ip4 : ip4.family == 0 ||
|
||||||
|
settings_get_bool("resolve_prefer_ipv6") ? &ip6 : &ip4;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = g_new0(LISTEN_REC, 1);
|
rec = g_new0(LISTEN_REC, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user