mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 07:23:53 +01:00
ircd: server connection configuration
Fix the server connection configuration so that it can simultaneously handle a hostname/IPv4/IPv6 for connecting and a hostname/IPv4/IPv6 for binding. Maintains backwards compatibility for matching a hostname with a mask. Multiple host/vhost entries can be specified and the last value for each address family is stored. Hostnames that resolve automatically overwrite the IP address. Server connections can now be made to either IPv4 or IPv6 at random as well as preferring a specific address family.
This commit is contained in:
parent
65f43a4fc4
commit
d4214e9445
9 changed files with 248 additions and 121 deletions
|
@ -310,10 +310,6 @@ connect "irc.uplink.com" {
|
|||
flags = compressed, topicburst;
|
||||
|
||||
#fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
|
||||
|
||||
/* If the connection is IPv6, uncomment below.
|
||||
* Use 0::1, not ::1, for IPv6 localhost. */
|
||||
#aftype = ipv6;
|
||||
};
|
||||
|
||||
connect "ssl.uplink.com" {
|
||||
|
@ -454,7 +450,7 @@ opm {
|
|||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost6.
|
||||
*/
|
||||
#listen_ipv6 = "0::1";
|
||||
#listen_ipv6 = "::1";
|
||||
|
||||
/* IPv6 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
|
|
|
@ -571,17 +571,14 @@ connect "irc.uplink.com" {
|
|||
};
|
||||
|
||||
connect "ipv6.lame.server" {
|
||||
/* Hosts that are IPv6 addresses must be in :: shortened form
|
||||
* if applicable. Addresses starting with a colon get an extra
|
||||
* zero prepended, for example: 0::1
|
||||
*/
|
||||
host = "192.0.2.1";
|
||||
host = "2001:db8:3::8";
|
||||
send_password = "password";
|
||||
accept_password = "password";
|
||||
port = 6666;
|
||||
|
||||
/* aftype: controls whether the connection uses "ipv4" or "ipv6".
|
||||
* Default is ipv4.
|
||||
/* aftype: controls whether the outgoing connection uses "ipv4" or "ipv6".
|
||||
* Default is to try either at random.
|
||||
*/
|
||||
aftype = ipv6;
|
||||
class = "server";
|
||||
|
@ -930,7 +927,7 @@ opm {
|
|||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost6.
|
||||
*/
|
||||
#listen_ipv6 = "0::1";
|
||||
#listen_ipv6 = "::1";
|
||||
|
||||
/* IPv6 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
|
|
|
@ -105,7 +105,7 @@ serverinfo {
|
|||
<term>vhost</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An optional text field which defines an IP from which to connect outward to other IRC servers.
|
||||
An optional text field which defines an IPv4 address from which to connect outward to other IRC servers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -113,7 +113,7 @@ serverinfo {
|
|||
<term>vhost6</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An optional text field which defines an IPv6 IP from which to connect outward to other IRC servers.
|
||||
An optional text field which defines an IPv6 address from which to connect outward to other IRC servers.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -599,10 +599,6 @@ connect "<replaceable>name</replaceable>" {
|
|||
Furthermore, if a hostname is used, it must have an A or AAAA
|
||||
record (no CNAME) and it must be the primary
|
||||
hostname for inbound connections to work.
|
||||
</para><para>
|
||||
IPv6 addresses must be in :: shortened form; addresses which
|
||||
then start with a colon must be prepended with a zero,
|
||||
for example 0::1.
|
||||
</para></note>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -662,7 +658,7 @@ connect "<replaceable>name</replaceable>" {
|
|||
<varlistentry>
|
||||
<term>aftype</term>
|
||||
<listitem>
|
||||
<para>The protocol that should be used to connect with, either ipv4 or ipv6. This defaults to ipv4 unless host is a numeric IPv6 address.</para>
|
||||
<para>The protocol that must be used to connect with, either ipv4 or ipv6. This defaults to neither, allowing connection using either address family.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
|
|
@ -282,14 +282,10 @@ struct server_info
|
|||
char *description;
|
||||
char *network_name;
|
||||
int hub;
|
||||
struct sockaddr_in ip;
|
||||
struct rb_sockaddr_storage bind4;
|
||||
int default_max_clients;
|
||||
#ifdef RB_IPV6
|
||||
struct sockaddr_in6 ip6;
|
||||
#endif
|
||||
int specific_ipv4_vhost;
|
||||
#ifdef RB_IPV6
|
||||
int specific_ipv6_vhost;
|
||||
struct rb_sockaddr_storage bind6;
|
||||
#endif
|
||||
char *ssl_private_key;
|
||||
char *ssl_ca_cert;
|
||||
|
|
|
@ -178,7 +178,13 @@ extern const char *get_oper_privs(int flags);
|
|||
struct server_conf
|
||||
{
|
||||
char *name;
|
||||
char *host;
|
||||
char *connect_host;
|
||||
struct rb_sockaddr_storage connect4;
|
||||
uint16_t dns_query_connect4;
|
||||
#ifdef RB_IPV6
|
||||
struct rb_sockaddr_storage connect6;
|
||||
uint16_t dns_query_connect6;
|
||||
#endif
|
||||
char *passwd;
|
||||
char *spasswd;
|
||||
char *certfp;
|
||||
|
@ -188,17 +194,20 @@ struct server_conf
|
|||
time_t hold;
|
||||
|
||||
int aftype;
|
||||
struct rb_sockaddr_storage my_ipnum;
|
||||
char *bind_host;
|
||||
struct rb_sockaddr_storage bind4;
|
||||
uint16_t dns_query_bind4;
|
||||
#ifdef RB_IPV6
|
||||
struct rb_sockaddr_storage bind6;
|
||||
uint16_t dns_query_bind6;
|
||||
#endif
|
||||
|
||||
char *class_name;
|
||||
struct Class *class;
|
||||
rb_dlink_node node;
|
||||
|
||||
uint16_t dns_query;
|
||||
};
|
||||
|
||||
#define SERVER_ILLEGAL 0x0001
|
||||
#define SERVER_VHOSTED 0x0002
|
||||
#define SERVER_ENCRYPTED 0x0004
|
||||
#define SERVER_COMPRESSED 0x0008
|
||||
#define SERVER_TB 0x0010
|
||||
|
@ -206,7 +215,6 @@ struct server_conf
|
|||
#define SERVER_SSL 0x0040
|
||||
|
||||
#define ServerConfIllegal(x) ((x)->flags & SERVER_ILLEGAL)
|
||||
#define ServerConfVhosted(x) ((x)->flags & SERVER_VHOSTED)
|
||||
#define ServerConfEncrypted(x) ((x)->flags & SERVER_ENCRYPTED)
|
||||
#define ServerConfCompressed(x) ((x)->flags & SERVER_COMPRESSED)
|
||||
#define ServerConfTb(x) ((x)->flags & SERVER_TB)
|
||||
|
|
|
@ -243,27 +243,31 @@ conf_set_serverinfo_network_name(void *data)
|
|||
static void
|
||||
conf_set_serverinfo_vhost(void *data)
|
||||
{
|
||||
if(rb_inet_pton(AF_INET, (char *) data, &ServerInfo.ip.sin_addr) <= 0)
|
||||
struct rb_sockaddr_storage addr;
|
||||
|
||||
if(rb_inet_pton_sock(data, (struct sockaddr *)&addr) <= 0 || GET_SS_FAMILY(&addr) != AF_INET)
|
||||
{
|
||||
conf_report_error("Invalid IPv4 address for server vhost (%s)", (char *) data);
|
||||
return;
|
||||
}
|
||||
ServerInfo.ip.sin_family = AF_INET;
|
||||
ServerInfo.specific_ipv4_vhost = 1;
|
||||
|
||||
ServerInfo.bind4 = addr;
|
||||
}
|
||||
|
||||
static void
|
||||
conf_set_serverinfo_vhost6(void *data)
|
||||
{
|
||||
|
||||
#ifdef RB_IPV6
|
||||
if(rb_inet_pton(AF_INET6, (char *) data, &ServerInfo.ip6.sin6_addr) <= 0)
|
||||
struct rb_sockaddr_storage addr;
|
||||
|
||||
if(rb_inet_pton_sock(data, (struct sockaddr *)&addr) <= 0 || GET_SS_FAMILY(&addr) != AF_INET6)
|
||||
{
|
||||
conf_report_error("Invalid IPv6 address for server vhost (%s)", (char *) data);
|
||||
return;
|
||||
}
|
||||
|
||||
ServerInfo.specific_ipv6_vhost = 1;
|
||||
ServerInfo.ip6.sin6_family = AF_INET6;
|
||||
ServerInfo.bind6 = addr;
|
||||
#else
|
||||
conf_report_error("Warning -- ignoring serverinfo::vhost6 -- IPv6 support not available.");
|
||||
#endif
|
||||
|
@ -1301,7 +1305,12 @@ conf_end_connect(struct TopConf *tc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(EmptyString(yy_server->host))
|
||||
if(EmptyString(yy_server->connect_host)
|
||||
&& GET_SS_FAMILY(&yy_server->connect4) != AF_INET
|
||||
#ifdef RB_IPV6
|
||||
&& GET_SS_FAMILY(&yy_server->connect6) != AF_INET6
|
||||
#endif
|
||||
)
|
||||
{
|
||||
conf_report_error("Ignoring connect block for %s -- missing host.",
|
||||
yy_server->name);
|
||||
|
@ -1326,23 +1335,57 @@ conf_end_connect(struct TopConf *tc)
|
|||
static void
|
||||
conf_set_connect_host(void *data)
|
||||
{
|
||||
rb_free(yy_server->host);
|
||||
yy_server->host = rb_strdup(data);
|
||||
if (strchr(yy_server->host, ':'))
|
||||
yy_server->aftype = AF_INET6;
|
||||
struct rb_sockaddr_storage addr;
|
||||
|
||||
if(rb_inet_pton_sock(data, (struct sockaddr *)&addr) <= 0)
|
||||
{
|
||||
rb_free(yy_server->connect_host);
|
||||
yy_server->connect_host = rb_strdup(data);
|
||||
}
|
||||
else if(GET_SS_FAMILY(&addr) == AF_INET)
|
||||
{
|
||||
yy_server->connect4 = addr;
|
||||
}
|
||||
#ifdef RB_IPV6
|
||||
else if(GET_SS_FAMILY(&addr) == AF_INET6)
|
||||
{
|
||||
yy_server->connect6 = addr;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
conf_report_error("Unsupported IP address for server connect host (%s)",
|
||||
(char *)data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
conf_set_connect_vhost(void *data)
|
||||
{
|
||||
if(rb_inet_pton_sock(data, (struct sockaddr *)&yy_server->my_ipnum) <= 0)
|
||||
struct rb_sockaddr_storage addr;
|
||||
|
||||
if(rb_inet_pton_sock(data, (struct sockaddr *)&addr) <= 0)
|
||||
{
|
||||
conf_report_error("Invalid IP address for server connect vhost (%s)",
|
||||
(char *) data);
|
||||
rb_free(yy_server->bind_host);
|
||||
yy_server->bind_host = rb_strdup(data);
|
||||
}
|
||||
else if(GET_SS_FAMILY(&addr) == AF_INET)
|
||||
{
|
||||
yy_server->bind4 = addr;
|
||||
}
|
||||
#ifdef RB_IPV6
|
||||
else if(GET_SS_FAMILY(&addr) == AF_INET6)
|
||||
{
|
||||
yy_server->bind6 = addr;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
conf_report_error("Unsupported IP address for server connect vhost (%s)",
|
||||
(char *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
yy_server->flags |= SERVER_VHOSTED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2071,7 +2114,7 @@ conf_end_opm(struct TopConf *tc)
|
|||
else
|
||||
{
|
||||
char ip[HOSTIPLEN];
|
||||
if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip, ip, sizeof(ip)))
|
||||
if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.bind4, ip, sizeof(ip)))
|
||||
conf_report_error("No opm::listen_ipv4 nor serverinfo::vhost directive; cannot listen on IPv4");
|
||||
else
|
||||
conf_create_opm_listener(ip, yy_opm_port_ipv4);
|
||||
|
@ -2085,7 +2128,7 @@ conf_end_opm(struct TopConf *tc)
|
|||
else
|
||||
{
|
||||
char ip[HOSTIPLEN];
|
||||
if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.ip6, ip, sizeof(ip)))
|
||||
if(!rb_inet_ntop_sock((struct sockaddr *)&ServerInfo.bind6, ip, sizeof(ip)))
|
||||
conf_report_error("No opm::listen_ipv6 nor serverinfo::vhost directive; cannot listen on IPv6");
|
||||
else
|
||||
conf_create_opm_listener(ip, yy_opm_port_ipv6);
|
||||
|
|
|
@ -680,11 +680,11 @@ set_default_conf(void)
|
|||
ServerInfo.description = NULL;
|
||||
ServerInfo.network_name = NULL;
|
||||
|
||||
memset(&ServerInfo.ip, 0, sizeof(ServerInfo.ip));
|
||||
ServerInfo.specific_ipv4_vhost = 0;
|
||||
memset(&ServerInfo.bind4, 0, sizeof(ServerInfo.bind4));
|
||||
SET_SS_FAMILY(&ServerInfo.bind4, AF_UNSPEC);
|
||||
#ifdef RB_IPV6
|
||||
memset(&ServerInfo.ip6, 0, sizeof(ServerInfo.ip6));
|
||||
ServerInfo.specific_ipv6_vhost = 0;
|
||||
memset(&ServerInfo.bind6, 0, sizeof(ServerInfo.bind6));
|
||||
SET_SS_FAMILY(&ServerInfo.bind6, AF_UNSPEC);
|
||||
#endif
|
||||
|
||||
AdminInfo.name = NULL;
|
||||
|
|
100
ircd/s_newconf.c
100
ircd/s_newconf.c
|
@ -324,8 +324,24 @@ struct server_conf *
|
|||
make_server_conf(void)
|
||||
{
|
||||
struct server_conf *server_p = rb_malloc(sizeof(struct server_conf));
|
||||
server_p->aftype = AF_INET;
|
||||
return server_p;
|
||||
|
||||
SET_SS_FAMILY(&server_p->connect4, AF_UNSPEC);
|
||||
SET_SS_LEN(&server_p->connect4, sizeof(struct sockaddr_in));
|
||||
|
||||
SET_SS_FAMILY(&server_p->bind4, AF_UNSPEC);
|
||||
SET_SS_LEN(&server_p->bind4, sizeof(struct sockaddr_in));
|
||||
|
||||
#ifdef RB_IPV6
|
||||
SET_SS_FAMILY(&server_p->connect6, AF_UNSPEC);
|
||||
SET_SS_LEN(&server_p->connect6, sizeof(struct sockaddr_in6));
|
||||
|
||||
SET_SS_FAMILY(&server_p->bind6, AF_UNSPEC);
|
||||
SET_SS_LEN(&server_p->bind6, sizeof(struct sockaddr_in6));
|
||||
#endif
|
||||
|
||||
server_p->aftype = AF_UNSPEC;
|
||||
|
||||
return rb_malloc(sizeof(struct server_conf));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -348,13 +364,14 @@ free_server_conf(struct server_conf *server_p)
|
|||
}
|
||||
|
||||
rb_free(server_p->name);
|
||||
rb_free(server_p->host);
|
||||
rb_free(server_p->connect_host);
|
||||
rb_free(server_p->bind_host);
|
||||
rb_free(server_p->class_name);
|
||||
rb_free(server_p);
|
||||
}
|
||||
|
||||
/*
|
||||
* conf_dns_callback
|
||||
* conf_connect_dns_callback
|
||||
* inputs - pointer to struct ConfItem
|
||||
* - pointer to adns reply
|
||||
* output - none
|
||||
|
@ -364,14 +381,59 @@ free_server_conf(struct server_conf *server_p)
|
|||
* if successful save hp in the conf item it was called with
|
||||
*/
|
||||
static void
|
||||
conf_dns_callback(const char *result, int status, int aftype, void *data)
|
||||
conf_connect_dns_callback(const char *result, int status, int aftype, void *data)
|
||||
{
|
||||
struct server_conf *server_p = data;
|
||||
|
||||
if(status == 1)
|
||||
rb_inet_pton_sock(result, (struct sockaddr *)&server_p->my_ipnum);
|
||||
if(aftype == AF_INET)
|
||||
{
|
||||
if(status == 1)
|
||||
rb_inet_pton_sock(result, (struct sockaddr *)&server_p->connect4);
|
||||
|
||||
server_p->dns_query = 0;
|
||||
server_p->dns_query_connect4 = 0;
|
||||
}
|
||||
#ifdef RB_IPV6
|
||||
else if(aftype == AF_INET6)
|
||||
{
|
||||
if(status == 1)
|
||||
rb_inet_pton_sock(result, (struct sockaddr *)&server_p->connect6);
|
||||
|
||||
server_p->dns_query_connect6 = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* conf_bind_dns_callback
|
||||
* inputs - pointer to struct ConfItem
|
||||
* - pointer to adns reply
|
||||
* output - none
|
||||
* side effects - called when resolver query finishes
|
||||
* if the query resulted in a successful search, hp will contain
|
||||
* a non-null pointer, otherwise hp will be null.
|
||||
* if successful save hp in the conf item it was called with
|
||||
*/
|
||||
static void
|
||||
conf_bind_dns_callback(const char *result, int status, int aftype, void *data)
|
||||
{
|
||||
struct server_conf *server_p = data;
|
||||
|
||||
if(aftype == AF_INET)
|
||||
{
|
||||
if(status == 1)
|
||||
rb_inet_pton_sock(result, (struct sockaddr *)&server_p->bind4);
|
||||
|
||||
server_p->dns_query_bind4 = 0;
|
||||
}
|
||||
#ifdef RB_IPV6
|
||||
else if(aftype == AF_INET6)
|
||||
{
|
||||
if(status == 1)
|
||||
rb_inet_pton_sock(result, (struct sockaddr *)&server_p->bind6);
|
||||
|
||||
server_p->dns_query_bind6 = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -395,11 +457,25 @@ add_server_conf(struct server_conf *server_p)
|
|||
server_p->class_name = rb_strdup("default");
|
||||
}
|
||||
|
||||
if(strpbrk(server_p->host, "*?"))
|
||||
return;
|
||||
if(server_p->connect_host && !strpbrk(server_p->connect_host, "*?"))
|
||||
{
|
||||
server_p->dns_query_connect4 =
|
||||
lookup_hostname(server_p->connect_host, AF_INET, conf_connect_dns_callback, server_p);
|
||||
#ifdef RB_IPV6
|
||||
server_p->dns_query_connect6 =
|
||||
lookup_hostname(server_p->connect_host, AF_INET6, conf_connect_dns_callback, server_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
server_p->dns_query =
|
||||
lookup_hostname(server_p->host, GET_SS_FAMILY(&server_p->my_ipnum), conf_dns_callback, server_p);
|
||||
if(server_p->bind_host)
|
||||
{
|
||||
server_p->dns_query_bind4 =
|
||||
lookup_hostname(server_p->bind_host, AF_INET, conf_bind_dns_callback, server_p);
|
||||
#ifdef RB_IPV6
|
||||
server_p->dns_query_bind6 =
|
||||
lookup_hostname(server_p->bind_host, AF_INET6, conf_bind_dns_callback, server_p);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
struct server_conf *
|
||||
|
|
127
ircd/s_serv.c
127
ircd/s_serv.c
|
@ -363,6 +363,8 @@ check_server(const char *name, struct Client *client_p)
|
|||
|
||||
RB_DLINK_FOREACH(ptr, server_conf_list.head)
|
||||
{
|
||||
struct rb_sockaddr_storage client_addr;
|
||||
|
||||
tmp_p = ptr->data;
|
||||
|
||||
if(ServerConfIllegal(tmp_p))
|
||||
|
@ -373,10 +375,19 @@ check_server(const char *name, struct Client *client_p)
|
|||
|
||||
name_matched = true;
|
||||
|
||||
/* XXX: Fix me for IPv6 */
|
||||
/* XXX sockhost is the IPv4 ip as a string */
|
||||
if(match(tmp_p->host, client_p->host) ||
|
||||
match(tmp_p->host, client_p->sockhost))
|
||||
if(rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&client_addr) <= 0)
|
||||
SET_SS_FAMILY(&client_addr, AF_UNSPEC);
|
||||
|
||||
if((tmp_p->connect_host && match(tmp_p->connect_host, client_p->host))
|
||||
|| (GET_SS_FAMILY(&client_addr) == GET_SS_FAMILY(&tmp_p->connect4)
|
||||
&& comp_with_mask_sock((struct sockaddr *)&client_addr,
|
||||
(struct sockaddr *)&tmp_p->connect4, 32))
|
||||
#ifdef RB_IPV6
|
||||
|| (GET_SS_FAMILY(&client_addr) == GET_SS_FAMILY(&tmp_p->connect6)
|
||||
&& comp_with_mask_sock((struct sockaddr *)&client_addr,
|
||||
(struct sockaddr *)&tmp_p->connect6, 128))
|
||||
#endif
|
||||
)
|
||||
{
|
||||
host_matched = true;
|
||||
|
||||
|
@ -1010,7 +1021,8 @@ int
|
|||
serv_connect(struct server_conf *server_p, struct Client *by)
|
||||
{
|
||||
struct Client *client_p;
|
||||
struct rb_sockaddr_storage myipnum;
|
||||
struct rb_sockaddr_storage sa_connect;
|
||||
struct rb_sockaddr_storage sa_bind;
|
||||
char note[HOSTLEN + 10];
|
||||
rb_fde_t *F;
|
||||
|
||||
|
@ -1018,8 +1030,39 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
if(server_p == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef RB_IPV6
|
||||
if(server_p->aftype != AF_UNSPEC
|
||||
&& GET_SS_FAMILY(&server_p->connect4) == AF_INET
|
||||
&& GET_SS_FAMILY(&server_p->connect6) == AF_INET6)
|
||||
{
|
||||
if(rand() % 2 == 0)
|
||||
{
|
||||
sa_connect = server_p->connect4;
|
||||
sa_bind = server_p->bind4;
|
||||
}
|
||||
else
|
||||
{
|
||||
sa_connect = server_p->connect6;
|
||||
sa_bind = server_p->bind6;
|
||||
}
|
||||
}
|
||||
else if(server_p->aftype == AF_INET || GET_SS_FAMILY(&server_p->connect4) == AF_INET)
|
||||
#endif
|
||||
{
|
||||
sa_connect = server_p->connect4;
|
||||
sa_bind = server_p->bind4;
|
||||
}
|
||||
#ifdef RB_IPV6
|
||||
else if(server_p->aftype == AF_INET6 || GET_SS_FAMILY(&server_p->connect6) == AF_INET6)
|
||||
{
|
||||
sa_connect = server_p->connect6;
|
||||
sa_bind = server_p->bind6;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* log */
|
||||
rb_inet_ntop_sock((struct sockaddr *)&server_p->my_ipnum, buf, sizeof(buf));
|
||||
buf[0] = 0;
|
||||
rb_inet_ntop_sock((struct sockaddr *)&sa_connect, buf, sizeof(buf));
|
||||
ilog(L_SERVER, "Connect to *[%s] @%s", server_p->name, buf);
|
||||
|
||||
/*
|
||||
|
@ -1037,7 +1080,12 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
}
|
||||
|
||||
/* create a socket for the server connection */
|
||||
if((F = rb_socket(GET_SS_FAMILY(&server_p->my_ipnum), SOCK_STREAM, 0, NULL)) == NULL)
|
||||
if(GET_SS_FAMILY(&sa_connect) == AF_UNSPEC)
|
||||
{
|
||||
ilog_error("unspecified socket address family");
|
||||
return 0;
|
||||
}
|
||||
else if((F = rb_socket(GET_SS_FAMILY(&sa_connect), SOCK_STREAM, 0, NULL)) == NULL)
|
||||
{
|
||||
ilog_error("opening a stream socket");
|
||||
return 0;
|
||||
|
@ -1052,11 +1100,14 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
|
||||
/* Copy in the server, hostname, fd */
|
||||
rb_strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
|
||||
rb_strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
|
||||
if(server_p->connect_host)
|
||||
rb_strlcpy(client_p->host, server_p->connect_host, sizeof(client_p->host));
|
||||
else
|
||||
rb_strlcpy(client_p->host, buf, sizeof(client_p->host));
|
||||
rb_strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
|
||||
client_p->localClient->F = F;
|
||||
/* shove the port number into the sockaddr */
|
||||
SET_SS_PORT(&server_p->my_ipnum, htons(server_p->port));
|
||||
SET_SS_PORT(&sa_connect, htons(server_p->port));
|
||||
|
||||
/*
|
||||
* Set up the initial server evilness, ripped straight from
|
||||
|
@ -1091,58 +1142,22 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
SetConnecting(client_p);
|
||||
rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
|
||||
|
||||
if(ServerConfVhosted(server_p))
|
||||
if(GET_SS_FAMILY(&sa_bind) == AF_UNSPEC)
|
||||
{
|
||||
memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
|
||||
SET_SS_FAMILY(&myipnum, GET_SS_FAMILY(&server_p->my_ipnum));
|
||||
SET_SS_PORT(&myipnum, 0);
|
||||
|
||||
}
|
||||
else if(GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET && ServerInfo.specific_ipv4_vhost)
|
||||
{
|
||||
memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum));
|
||||
SET_SS_FAMILY(&myipnum, AF_INET);
|
||||
SET_SS_PORT(&myipnum, 0);
|
||||
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
if(GET_SS_FAMILY(&sa_connect) == GET_SS_FAMILY(&ServerInfo.bind4))
|
||||
sa_bind = ServerInfo.bind4;
|
||||
#ifdef RB_IPV6
|
||||
else if((GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET6) && ServerInfo.specific_ipv6_vhost)
|
||||
{
|
||||
memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
|
||||
SET_SS_FAMILY(&myipnum, AF_INET6);
|
||||
SET_SS_PORT(&myipnum, 0);
|
||||
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
|
||||
}
|
||||
if(GET_SS_FAMILY(&sa_connect) == GET_SS_FAMILY(&ServerInfo.bind6))
|
||||
sa_bind = ServerInfo.bind6;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if(ServerConfSSL(server_p))
|
||||
{
|
||||
rb_connect_tcp(client_p->localClient->F,
|
||||
(struct sockaddr *)&server_p->my_ipnum, NULL, 0,
|
||||
serv_connect_ssl_callback, client_p,
|
||||
ConfigFileEntry.connect_timeout);
|
||||
}
|
||||
else
|
||||
rb_connect_tcp(client_p->localClient->F,
|
||||
(struct sockaddr *)&server_p->my_ipnum, NULL, 0,
|
||||
serv_connect_callback, client_p,
|
||||
ConfigFileEntry.connect_timeout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
if(ServerConfSSL(server_p))
|
||||
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&server_p->my_ipnum,
|
||||
(struct sockaddr *)&myipnum,
|
||||
GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p,
|
||||
ConfigFileEntry.connect_timeout);
|
||||
else
|
||||
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&server_p->my_ipnum,
|
||||
(struct sockaddr *)&myipnum,
|
||||
GET_SS_LEN(&myipnum), serv_connect_callback, client_p,
|
||||
ConfigFileEntry.connect_timeout);
|
||||
|
||||
rb_connect_tcp(client_p->localClient->F,
|
||||
(struct sockaddr *)&sa_connect,
|
||||
GET_SS_FAMILY(&sa_bind) == AF_UNSPEC ? NULL : (struct sockaddr *)&sa_bind,
|
||||
GET_SS_LEN(&sa_bind),
|
||||
ServerConfSSL(server_p) ? serv_connect_ssl_callback : serv_connect_callback,
|
||||
client_p, ConfigFileEntry.connect_timeout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue