mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Merge pull request #1146 from slingamn/issue641_ipv6_failover.1
Reconnect retry IPv4 on IPv6 failure
This commit is contained in:
commit
6e14acee17
@ -11,6 +11,7 @@ int proxy_port;
|
|||||||
char *proxy_string, *proxy_string_after, *proxy_password;
|
char *proxy_string, *proxy_string_after, *proxy_password;
|
||||||
|
|
||||||
unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */
|
unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */
|
||||||
|
unsigned short chosen_family; /* family actually chosen during name resolution */
|
||||||
char *tag; /* try to keep this tag when connected to server */
|
char *tag; /* try to keep this tag when connected to server */
|
||||||
char *address;
|
char *address;
|
||||||
int port;
|
int port;
|
||||||
@ -43,5 +44,6 @@ unsigned int unix_socket:1; /* Connect using named unix socket */
|
|||||||
unsigned int use_tls:1; /* this connection uses TLS */
|
unsigned int use_tls:1; /* this connection uses TLS */
|
||||||
unsigned int tls_verify:1;
|
unsigned int tls_verify:1;
|
||||||
unsigned int no_connect:1; /* don't connect() at all, it's done by plugin */
|
unsigned int no_connect:1; /* don't connect() at all, it's done by plugin */
|
||||||
|
unsigned short last_failed_family; /* #641: if we failed to connect to ipv6, try ipv4 and vice versa */
|
||||||
char *channels;
|
char *channels;
|
||||||
char *away_reason;
|
char *away_reason;
|
||||||
|
@ -168,6 +168,7 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
|
|||||||
server_connect_ref(dest);
|
server_connect_ref(dest);
|
||||||
dest->type = module_get_uniq_id("SERVER CONNECT", 0);
|
dest->type = module_get_uniq_id("SERVER CONNECT", 0);
|
||||||
dest->reconnection = src->reconnection;
|
dest->reconnection = src->reconnection;
|
||||||
|
dest->last_failed_family = src->last_failed_family;
|
||||||
dest->proxy = g_strdup(src->proxy);
|
dest->proxy = g_strdup(src->proxy);
|
||||||
dest->proxy_port = src->proxy_port;
|
dest->proxy_port = src->proxy_port;
|
||||||
dest->proxy_string = g_strdup(src->proxy_string);
|
dest->proxy_string = g_strdup(src->proxy_string);
|
||||||
|
@ -156,6 +156,7 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
|
|||||||
error = net_geterror(handle);
|
error = net_geterror(handle);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
server->connection_lost = TRUE;
|
server->connection_lost = TRUE;
|
||||||
|
server->connrec->last_failed_family = server->connrec->chosen_family;
|
||||||
server_connect_failed(server, g_strerror(error));
|
server_connect_failed(server, g_strerror(error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -176,6 +177,7 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han
|
|||||||
error = irssi_ssl_handshake(handle);
|
error = irssi_ssl_handshake(handle);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
server->connection_lost = TRUE;
|
server->connection_lost = TRUE;
|
||||||
|
server->connrec->last_failed_family = server->connrec->chosen_family;
|
||||||
server_connect_failed(server, NULL);
|
server_connect_failed(server, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -216,6 +218,7 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (ip != NULL) {
|
if (ip != NULL) {
|
||||||
|
server->connrec->chosen_family = ip->family;
|
||||||
own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
|
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;
|
||||||
@ -241,9 +244,11 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||||||
server->no_reconnect = TRUE;
|
server->no_reconnect = TRUE;
|
||||||
|
|
||||||
server->connection_lost = TRUE;
|
server->connection_lost = TRUE;
|
||||||
|
server->connrec->last_failed_family = ip->family;
|
||||||
server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
|
server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
|
||||||
g_free(errmsg2);
|
g_free(errmsg2);
|
||||||
} else {
|
} else {
|
||||||
|
server->connrec->last_failed_family = 0;
|
||||||
server->handle = net_sendbuffer_create(handle, 0);
|
server->handle = net_sendbuffer_create(handle, 0);
|
||||||
if (server->connrec->use_tls)
|
if (server->connrec->use_tls)
|
||||||
server_connect_callback_init_ssl(server, handle);
|
server_connect_callback_init_ssl(server, handle);
|
||||||
@ -286,11 +291,15 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
|
|||||||
/* force IPv6 connection */
|
/* force IPv6 connection */
|
||||||
ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6;
|
ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6;
|
||||||
} else {
|
} else {
|
||||||
/* pick the one that was found, or if both do it like
|
/* pick the one that was found. if both were found:
|
||||||
/SET resolve_prefer_ipv6 says. */
|
1. disprefer the last one that failed
|
||||||
|
2. prefer ipv4 over ipv6 unless resolve_prefer_ipv6 is set
|
||||||
|
*/
|
||||||
if (iprec.ip4.family == 0 ||
|
if (iprec.ip4.family == 0 ||
|
||||||
(iprec.ip6.family != 0 &&
|
(iprec.ip6.family != 0 &&
|
||||||
settings_get_bool("resolve_prefer_ipv6"))) {
|
(server->connrec->last_failed_family == AF_INET ||
|
||||||
|
(settings_get_bool("resolve_prefer_ipv6") &&
|
||||||
|
server->connrec->last_failed_family != AF_INET6)))) {
|
||||||
ip = &iprec.ip6;
|
ip = &iprec.ip6;
|
||||||
} else {
|
} else {
|
||||||
ip = &iprec.ip4;
|
ip = &iprec.ip4;
|
||||||
|
Loading…
Reference in New Issue
Block a user