ircd: move DNS resolution over to authd
This commit is contained in:
parent
c7c009b563
commit
1d02144f8b
9 changed files with 115 additions and 257 deletions
|
@ -46,7 +46,7 @@ struct Blacklist {
|
||||||
struct BlacklistClient {
|
struct BlacklistClient {
|
||||||
struct Blacklist *blacklist;
|
struct Blacklist *blacklist;
|
||||||
struct Client *client_p;
|
struct Client *client_p;
|
||||||
struct DNSQuery dns_query;
|
uint16_t dns_id;
|
||||||
rb_dlink_node node;
|
rb_dlink_node node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -236,8 +236,6 @@ struct LocalUser
|
||||||
/* time challenge response is valid for */
|
/* time challenge response is valid for */
|
||||||
time_t chal_time;
|
time_t chal_time;
|
||||||
|
|
||||||
struct DNSQuery *dnsquery; /* for outgoing server's name lookup */
|
|
||||||
|
|
||||||
time_t next_away; /* Don't allow next away before... */
|
time_t next_away; /* Don't allow next away before... */
|
||||||
time_t last;
|
time_t last;
|
||||||
uint32_t connid;
|
uint32_t connid;
|
||||||
|
|
|
@ -41,7 +41,6 @@ struct Listener
|
||||||
int ssl; /* ssl listener */
|
int ssl; /* ssl listener */
|
||||||
int defer_accept; /* use TCP_DEFER_ACCEPT */
|
int defer_accept; /* use TCP_DEFER_ACCEPT */
|
||||||
struct rb_sockaddr_storage addr;
|
struct rb_sockaddr_storage addr;
|
||||||
struct DNSQuery *dns_query;
|
|
||||||
char vhost[HOSTLEN + 1]; /* virtual name of listener */
|
char vhost[HOSTLEN + 1]; /* virtual name of listener */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,8 @@ struct server_conf
|
||||||
char *class_name;
|
char *class_name;
|
||||||
struct Class *class;
|
struct Class *class;
|
||||||
rb_dlink_node node;
|
rb_dlink_node node;
|
||||||
|
|
||||||
|
uint16_t dns_query;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_ILLEGAL 0x0001
|
#define SERVER_ILLEGAL 0x0001
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "res.h"
|
#include "dns.h"
|
||||||
#include "numeric.h"
|
#include "numeric.h"
|
||||||
#include "reject.h"
|
#include "reject.h"
|
||||||
#include "s_conf.h"
|
#include "s_conf.h"
|
||||||
|
@ -60,27 +60,16 @@ static struct Blacklist *find_blacklist(char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int blacklist_check_reply(struct BlacklistClient *blcptr, struct rb_sockaddr_storage *addr)
|
static inline int blacklist_check_reply(struct BlacklistClient *blcptr, const char *ipaddr)
|
||||||
{
|
{
|
||||||
struct Blacklist *blptr = blcptr->blacklist;
|
struct Blacklist *blptr = blcptr->blacklist;
|
||||||
char ipaddr[HOSTIPLEN];
|
const char *lastoctet;
|
||||||
char *lastoctet;
|
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
|
|
||||||
/* XXX the below two checks might want to change at some point
|
|
||||||
* e.g. if IPv6 blacklists don't use 127.x.y.z or A records anymore
|
|
||||||
* --Elizabeth
|
|
||||||
*/
|
|
||||||
if (addr->ss_family != AF_INET ||
|
|
||||||
memcmp(&((struct sockaddr_in *)addr)->sin_addr, "\177", 1))
|
|
||||||
goto blwarn;
|
|
||||||
|
|
||||||
/* No filters and entry found - thus positive match */
|
/* No filters and entry found - thus positive match */
|
||||||
if (!rb_dlink_list_length(&blptr->filters))
|
if (!rb_dlink_list_length(&blptr->filters))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
rb_inet_ntop_sock((struct sockaddr *)addr, ipaddr, sizeof(ipaddr));
|
|
||||||
|
|
||||||
/* Below will prolly have to change too if the above changes */
|
/* Below will prolly have to change too if the above changes */
|
||||||
if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
|
if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
|
||||||
goto blwarn;
|
goto blwarn;
|
||||||
|
@ -88,7 +77,7 @@ static inline int blacklist_check_reply(struct BlacklistClient *blcptr, struct r
|
||||||
RB_DLINK_FOREACH(ptr, blcptr->blacklist->filters.head)
|
RB_DLINK_FOREACH(ptr, blcptr->blacklist->filters.head)
|
||||||
{
|
{
|
||||||
struct BlacklistFilter *filter = ptr->data;
|
struct BlacklistFilter *filter = ptr->data;
|
||||||
char *cmpstr;
|
const char *cmpstr;
|
||||||
|
|
||||||
if (filter->type == BLACKLIST_FILTER_ALL)
|
if (filter->type == BLACKLIST_FILTER_ALL)
|
||||||
cmpstr = ipaddr;
|
cmpstr = ipaddr;
|
||||||
|
@ -118,7 +107,7 @@ blwarn:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blacklist_dns_callback(void *vptr, struct DNSReply *reply)
|
static void blacklist_dns_callback(const char *result, int status, int aftype, void *vptr)
|
||||||
{
|
{
|
||||||
struct BlacklistClient *blcptr = (struct BlacklistClient *) vptr;
|
struct BlacklistClient *blcptr = (struct BlacklistClient *) vptr;
|
||||||
int listed = 0;
|
int listed = 0;
|
||||||
|
@ -134,9 +123,9 @@ static void blacklist_dns_callback(void *vptr, struct DNSReply *reply)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply != NULL)
|
if (result != NULL && status)
|
||||||
{
|
{
|
||||||
if (blacklist_check_reply(blcptr, &reply->addr))
|
if (blacklist_check_reply(blcptr, result))
|
||||||
listed = TRUE;
|
listed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,9 +156,6 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
|
||||||
blcptr->blacklist = blptr;
|
blcptr->blacklist = blptr;
|
||||||
blcptr->client_p = client_p;
|
blcptr->client_p = client_p;
|
||||||
|
|
||||||
blcptr->dns_query.ptr = blcptr;
|
|
||||||
blcptr->dns_query.callback = blacklist_dns_callback;
|
|
||||||
|
|
||||||
if ((client_p->localClient->ip.ss_family == AF_INET) && blptr->ipv4)
|
if ((client_p->localClient->ip.ss_family == AF_INET) && blptr->ipv4)
|
||||||
{
|
{
|
||||||
ip = (uint8_t *)&((struct sockaddr_in *)&client_p->localClient->ip)->sin_addr.s_addr;
|
ip = (uint8_t *)&((struct sockaddr_in *)&client_p->localClient->ip)->sin_addr.s_addr;
|
||||||
|
@ -219,7 +205,7 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gethost_byname_type(buf, &blcptr->dns_query, T_A);
|
blcptr->dns_id = lookup_hostname(buf, AF_INET, blacklist_dns_callback, blcptr);
|
||||||
|
|
||||||
rb_dlinkAdd(blcptr, &blcptr->node, &client_p->preClient->dnsbl_queries);
|
rb_dlinkAdd(blcptr, &blcptr->node, &client_p->preClient->dnsbl_queries);
|
||||||
blptr->refcount++;
|
blptr->refcount++;
|
||||||
|
@ -297,7 +283,7 @@ void abort_blacklist_queries(struct Client *client_p)
|
||||||
blcptr = ptr->data;
|
blcptr = ptr->data;
|
||||||
rb_dlinkDelete(&blcptr->node, &client_p->preClient->dnsbl_queries);
|
rb_dlinkDelete(&blcptr->node, &client_p->preClient->dnsbl_queries);
|
||||||
unref_blacklist(blcptr->blacklist);
|
unref_blacklist(blcptr->blacklist);
|
||||||
delete_resolver_queries(&blcptr->dns_query);
|
cancel_lookup(blcptr->dns_id);
|
||||||
rb_free(blcptr);
|
rb_free(blcptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1300,11 +1300,6 @@ exit_unknown_client(struct Client *client_p, struct Client *source_p, struct Cli
|
||||||
{
|
{
|
||||||
delete_auth_queries(source_p);
|
delete_auth_queries(source_p);
|
||||||
abort_blacklist_queries(source_p);
|
abort_blacklist_queries(source_p);
|
||||||
if (source_p->localClient->dnsquery)
|
|
||||||
{
|
|
||||||
delete_resolver_queries(source_p->localClient->dnsquery);
|
|
||||||
rb_free(source_p->localClient->dnsquery);
|
|
||||||
}
|
|
||||||
rb_dlinkDelete(&source_p->localClient->tnode, &unknown_list);
|
rb_dlinkDelete(&source_p->localClient->tnode, &unknown_list);
|
||||||
|
|
||||||
if(!IsIOError(source_p))
|
if(!IsIOError(source_p))
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "ircd.h"
|
#include "ircd.h"
|
||||||
#include "numeric.h"
|
#include "numeric.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "res.h"
|
#include "dns.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "s_stats.h"
|
#include "s_stats.h"
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
|
@ -55,7 +55,7 @@ struct AuthRequest
|
||||||
{
|
{
|
||||||
rb_dlink_node node;
|
rb_dlink_node node;
|
||||||
struct Client *client; /* pointer to client struct for request */
|
struct Client *client; /* pointer to client struct for request */
|
||||||
struct DNSQuery dns_query; /* DNS Query */
|
uint16_t dns_id; /* DNS Query */
|
||||||
unsigned int flags; /* current state of request */
|
unsigned int flags; /* current state of request */
|
||||||
rb_fde_t *F; /* file descriptor for auth queries */
|
rb_fde_t *F; /* file descriptor for auth queries */
|
||||||
time_t timeout; /* time when query expires */
|
time_t timeout; /* time when query expires */
|
||||||
|
@ -198,7 +198,7 @@ release_auth_client(struct AuthRequest *auth)
|
||||||
* of success of failure
|
* of success of failure
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
auth_dns_callback(void *vptr, struct DNSReply *reply)
|
auth_dns_callback(const char *result, int status, int aftype, void *vptr)
|
||||||
{
|
{
|
||||||
struct AuthRequest *auth = (struct AuthRequest *) vptr;
|
struct AuthRequest *auth = (struct AuthRequest *) vptr;
|
||||||
ClearDNSPending(auth);
|
ClearDNSPending(auth);
|
||||||
|
@ -216,50 +216,16 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(reply)
|
if(result != NULL && status)
|
||||||
{
|
{
|
||||||
int good = 1;
|
int good = 1;
|
||||||
|
|
||||||
if(auth->client->localClient->ip.ss_family == AF_INET)
|
if(good && strlen(result) <= HOSTLEN)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *ip, *ip_fwd;
|
rb_strlcpy(auth->client->host, result, sizeof(auth->client->host));
|
||||||
|
|
||||||
ip = (struct sockaddr_in *) &auth->client->localClient->ip;
|
|
||||||
ip_fwd = (struct sockaddr_in *) &reply->addr;
|
|
||||||
|
|
||||||
if(ip->sin_addr.s_addr != ip_fwd->sin_addr.s_addr)
|
|
||||||
{
|
|
||||||
sendheader(auth->client, REPORT_HOST_MISMATCH);
|
|
||||||
good = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
else if(auth->client->localClient->ip.ss_family == AF_INET6)
|
|
||||||
{
|
|
||||||
struct sockaddr_in6 *ip, *ip_fwd;
|
|
||||||
|
|
||||||
ip = (struct sockaddr_in6 *) &auth->client->localClient->ip;
|
|
||||||
ip_fwd = (struct sockaddr_in6 *) &reply->addr;
|
|
||||||
|
|
||||||
if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) != 0)
|
|
||||||
{
|
|
||||||
sendheader(auth->client, REPORT_HOST_MISMATCH);
|
|
||||||
good = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else /* can't verify it, don't know how. reject it. */
|
|
||||||
{
|
|
||||||
sendheader(auth->client, REPORT_HOST_UNKNOWN);
|
|
||||||
good = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(good && strlen(reply->h_name) <= HOSTLEN)
|
|
||||||
{
|
|
||||||
rb_strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host));
|
|
||||||
sendheader(auth->client, REPORT_FIN_DNS);
|
sendheader(auth->client, REPORT_FIN_DNS);
|
||||||
}
|
}
|
||||||
else if (strlen(reply->h_name) > HOSTLEN)
|
else if (strlen(result) > HOSTLEN)
|
||||||
sendheader(auth->client, REPORT_HOST_TOOLONG);
|
sendheader(auth->client, REPORT_HOST_TOOLONG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -447,13 +413,10 @@ start_auth(struct Client *client)
|
||||||
|
|
||||||
auth = make_auth_request(client);
|
auth = make_auth_request(client);
|
||||||
|
|
||||||
auth->dns_query.ptr = auth;
|
|
||||||
auth->dns_query.callback = auth_dns_callback;
|
|
||||||
|
|
||||||
sendheader(client, REPORT_DO_DNS);
|
sendheader(client, REPORT_DO_DNS);
|
||||||
|
|
||||||
/* No DNS cache now, remember? -- adrian */
|
/* No DNS cache now, remember? -- adrian */
|
||||||
gethost_byaddr(&client->localClient->ip, &auth->dns_query);
|
auth->dns_id = lookup_ip(client->sockhost, GET_SS_FAMILY(&client->localClient->ip), auth_dns_callback, auth);
|
||||||
|
|
||||||
SetDNSPending(auth);
|
SetDNSPending(auth);
|
||||||
|
|
||||||
|
@ -493,7 +456,7 @@ timeout_auth_queries_event(void *notused)
|
||||||
if(IsDNSPending(auth))
|
if(IsDNSPending(auth))
|
||||||
{
|
{
|
||||||
ClearDNSPending(auth);
|
ClearDNSPending(auth);
|
||||||
delete_resolver_queries(&auth->dns_query);
|
cancel_lookup(auth->dns_id);
|
||||||
sendheader(auth->client, REPORT_FAIL_DNS);
|
sendheader(auth->client, REPORT_FAIL_DNS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +599,7 @@ delete_auth_queries(struct Client *target_p)
|
||||||
target_p->localClient->auth_request = NULL;
|
target_p->localClient->auth_request = NULL;
|
||||||
|
|
||||||
if(IsDNSPending(auth))
|
if(IsDNSPending(auth))
|
||||||
delete_resolver_queries(&auth->dns_query);
|
cancel_lookup(auth->dns_id);
|
||||||
|
|
||||||
if(auth->F != NULL)
|
if(auth->F != NULL)
|
||||||
rb_close(auth->F);
|
rb_close(auth->F);
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "irc_dictionary.h"
|
#include "irc_dictionary.h"
|
||||||
#include "s_assert.h"
|
#include "s_assert.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "dns.h"
|
||||||
|
|
||||||
rb_dlink_list shared_conf_list;
|
rb_dlink_list shared_conf_list;
|
||||||
rb_dlink_list cluster_conf_list;
|
rb_dlink_list cluster_conf_list;
|
||||||
|
@ -354,6 +355,27 @@ free_server_conf(struct server_conf *server_p)
|
||||||
rb_free(server_p);
|
rb_free(server_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* conf_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_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);
|
||||||
|
|
||||||
|
server_p->dns_query = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_server_conf(struct server_conf *server_p)
|
add_server_conf(struct server_conf *server_p)
|
||||||
{
|
{
|
||||||
|
@ -375,8 +397,11 @@ add_server_conf(struct server_conf *server_p)
|
||||||
server_p->class_name = rb_strdup("default");
|
server_p->class_name = rb_strdup("default");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strchr(server_p->host, '*') || strchr(server_p->host, '?'))
|
if(strpbrk(server_p->host, "*?"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
server_p->dns_query =
|
||||||
|
lookup_hostname(server_p->host, GET_SS_FAMILY(&server_p->my_ipnum), conf_dns_callback, server_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct server_conf *
|
struct server_conf *
|
||||||
|
|
246
ircd/s_serv.c
246
ircd/s_serv.c
|
@ -971,135 +971,6 @@ server_estab(struct Client *client_p)
|
||||||
* -- adrian
|
* -- adrian
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
|
||||||
serv_connect_resolved(struct Client *client_p)
|
|
||||||
{
|
|
||||||
struct rb_sockaddr_storage myipnum;
|
|
||||||
char vhoststr[HOSTIPLEN];
|
|
||||||
struct server_conf *server_p;
|
|
||||||
uint16_t port;
|
|
||||||
|
|
||||||
if((server_p = client_p->localClient->att_sconf) == NULL)
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Lost connect{} block for %s",
|
|
||||||
client_p->name);
|
|
||||||
exit_client(client_p, client_p, &me, "Lost connect{} block");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
if(client_p->localClient->ip.ss_family == AF_INET6)
|
|
||||||
port = ntohs(((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
port = ntohs(((struct sockaddr_in *)&client_p->localClient->ip)->sin_port);
|
|
||||||
|
|
||||||
if(ServerConfVhosted(server_p))
|
|
||||||
{
|
|
||||||
memcpy(&myipnum, &server_p->my_ipnum, sizeof(server_p->my_ipnum));
|
|
||||||
((struct sockaddr_in *)&myipnum)->sin_port = 0;
|
|
||||||
myipnum.ss_family = server_p->aftype;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(server_p->aftype == AF_INET && ServerInfo.specific_ipv4_vhost)
|
|
||||||
{
|
|
||||||
memcpy(&myipnum, &ServerInfo.ip, sizeof(ServerInfo.ip));
|
|
||||||
((struct sockaddr_in *)&myipnum)->sin_port = 0;
|
|
||||||
myipnum.ss_family = AF_INET;
|
|
||||||
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost)
|
|
||||||
{
|
|
||||||
memcpy(&myipnum, &ServerInfo.ip6, sizeof(ServerInfo.ip6));
|
|
||||||
((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
|
|
||||||
myipnum.ss_family = AF_INET6;
|
|
||||||
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* log */
|
|
||||||
ilog(L_SERVER, "Connecting to %s[%s] port %d (%s)", client_p->name, client_p->sockhost, port,
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
server_p->aftype == AF_INET6 ? "IPv6" :
|
|
||||||
#endif
|
|
||||||
(server_p->aftype == AF_INET ? "IPv4" : "?"));
|
|
||||||
|
|
||||||
if(ServerConfSSL(server_p))
|
|
||||||
{
|
|
||||||
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
|
|
||||||
NULL, 0, serv_connect_ssl_callback,
|
|
||||||
client_p, ConfigFileEntry.connect_timeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
|
|
||||||
NULL, 0, serv_connect_callback,
|
|
||||||
client_p, ConfigFileEntry.connect_timeout);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* log */
|
|
||||||
rb_inet_ntop_sock((struct sockaddr *)&myipnum, vhoststr, sizeof vhoststr);
|
|
||||||
ilog(L_SERVER, "Connecting to %s[%s] port %d (%s) (vhost %s)", client_p->name, client_p->sockhost, port,
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
server_p->aftype == AF_INET6 ? "IPv6" :
|
|
||||||
#endif
|
|
||||||
(server_p->aftype == AF_INET ? "IPv4" : "?"), vhoststr);
|
|
||||||
|
|
||||||
|
|
||||||
if(ServerConfSSL(server_p))
|
|
||||||
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
|
|
||||||
(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 *)&client_p->localClient->ip,
|
|
||||||
(struct sockaddr *) &myipnum,
|
|
||||||
GET_SS_LEN(&myipnum), serv_connect_callback, client_p,
|
|
||||||
ConfigFileEntry.connect_timeout);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
serv_connect_dns_callback(void *vptr, struct DNSReply *reply)
|
|
||||||
{
|
|
||||||
struct Client *client_p = vptr;
|
|
||||||
uint16_t port;
|
|
||||||
|
|
||||||
rb_free(client_p->localClient->dnsquery);
|
|
||||||
client_p->localClient->dnsquery = NULL;
|
|
||||||
|
|
||||||
if (reply == NULL)
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Cannot resolve hostname for %s",
|
|
||||||
client_p->name);
|
|
||||||
ilog(L_SERVER, "Cannot resolve hostname for %s",
|
|
||||||
log_client_name(client_p, HIDE_IP));
|
|
||||||
exit_client(client_p, client_p, &me, "Cannot resolve hostname");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
if(reply->addr.ss_family == AF_INET6)
|
|
||||||
port = ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
port = ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port;
|
|
||||||
memcpy(&client_p->localClient->ip, &reply->addr, sizeof(client_p->localClient->ip));
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
if(reply->addr.ss_family == AF_INET6)
|
|
||||||
((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = port;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = port;
|
|
||||||
/* Set sockhost properly now -- jilles */
|
|
||||||
rb_inet_ntop_sock((struct sockaddr *)&client_p->localClient->ip,
|
|
||||||
client_p->sockhost, sizeof client_p->sockhost);
|
|
||||||
serv_connect_resolved(client_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* serv_connect() - initiate a server connection
|
* serv_connect() - initiate a server connection
|
||||||
*
|
*
|
||||||
|
@ -1121,14 +992,18 @@ int
|
||||||
serv_connect(struct server_conf *server_p, struct Client *by)
|
serv_connect(struct server_conf *server_p, struct Client *by)
|
||||||
{
|
{
|
||||||
struct Client *client_p;
|
struct Client *client_p;
|
||||||
struct rb_sockaddr_storage theiripnum;
|
struct rb_sockaddr_storage myipnum;
|
||||||
rb_fde_t *F;
|
|
||||||
char note[HOSTLEN + 10];
|
char note[HOSTLEN + 10];
|
||||||
|
rb_fde_t *F;
|
||||||
|
|
||||||
s_assert(server_p != NULL);
|
s_assert(server_p != NULL);
|
||||||
if(server_p == NULL)
|
if(server_p == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* log */
|
||||||
|
rb_inet_ntop_sock((struct sockaddr *)&server_p->my_ipnum, buf, sizeof(buf));
|
||||||
|
ilog(L_SERVER, "Connect to *[%s] @%s", server_p->name, buf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure this server isn't already connected
|
* Make sure this server isn't already connected
|
||||||
*/
|
*/
|
||||||
|
@ -1144,27 +1019,32 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a socket for the server connection */
|
/* create a socket for the server connection */
|
||||||
if((F = rb_socket(server_p->aftype, SOCK_STREAM, 0, NULL)) == NULL)
|
if((F = rb_socket(GET_SS_FAMILY(&server_p->my_ipnum), SOCK_STREAM, 0, NULL)) == NULL)
|
||||||
{
|
{
|
||||||
ilog_error("opening a stream socket");
|
ilog_error("opening a stream socket");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_snprintf(note, sizeof note, "Server: %s", server_p->name);
|
/* servernames are always guaranteed under HOSTLEN chars */
|
||||||
|
rb_snprintf(note, sizeof(note), "Server: %s", server_p->name);
|
||||||
rb_note(F, note);
|
rb_note(F, note);
|
||||||
|
|
||||||
/* Create a local client */
|
/* Create a local client */
|
||||||
client_p = make_client(NULL);
|
client_p = make_client(NULL);
|
||||||
|
|
||||||
/* Copy in the server, hostname, fd
|
/* Copy in the server, hostname, fd */
|
||||||
* The sockhost may be a hostname, this will be corrected later
|
|
||||||
* -- jilles
|
|
||||||
*/
|
|
||||||
rb_strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
|
rb_strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
|
||||||
rb_strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
|
rb_strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
|
||||||
rb_strlcpy(client_p->sockhost, server_p->host, sizeof(client_p->sockhost));
|
rb_strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
|
||||||
client_p->localClient->F = F;
|
client_p->localClient->F = F;
|
||||||
add_to_cli_connid_hash(client_p);
|
add_to_cli_connid_hash(client_p);
|
||||||
|
/* shove the port number into the sockaddr */
|
||||||
|
#ifdef RB_IPV6
|
||||||
|
if(GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET6)
|
||||||
|
((struct sockaddr_in6 *)&server_p->my_ipnum)->sin6_port = htons(server_p->port);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
((struct sockaddr_in *)&server_p->my_ipnum)->sin_port = htons(server_p->port);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the initial server evilness, ripped straight from
|
* Set up the initial server evilness, ripped straight from
|
||||||
|
@ -1191,57 +1071,67 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
||||||
* The socket has been connected or connect is in progress.
|
* The socket has been connected or connect is in progress.
|
||||||
*/
|
*/
|
||||||
make_server(client_p);
|
make_server(client_p);
|
||||||
if(by && IsPerson(by))
|
if(by && IsClient(by))
|
||||||
{
|
strcpy(client_p->serv->by, by->name);
|
||||||
rb_strlcpy(client_p->serv->by, by->name,
|
|
||||||
sizeof client_p->serv->by);
|
|
||||||
if(client_p->serv->user)
|
|
||||||
free_user(client_p->serv->user, NULL);
|
|
||||||
client_p->serv->user = by->user;
|
|
||||||
by->user->refcnt++;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
strcpy(client_p->serv->by, "AutoConn.");
|
||||||
rb_strlcpy(client_p->serv->by, "AutoConn.",
|
|
||||||
sizeof client_p->serv->by);
|
|
||||||
if(client_p->serv->user)
|
|
||||||
free_user(client_p->serv->user, NULL);
|
|
||||||
client_p->serv->user = NULL;
|
|
||||||
}
|
|
||||||
SetConnecting(client_p);
|
SetConnecting(client_p);
|
||||||
rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
|
rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
|
||||||
|
|
||||||
if (rb_inet_pton_sock(server_p->host, (struct sockaddr *)&theiripnum) > 0)
|
if(ServerConfVhosted(server_p))
|
||||||
{
|
{
|
||||||
memcpy(&client_p->localClient->ip, &theiripnum, sizeof(client_p->localClient->ip));
|
memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
|
||||||
#ifdef RB_IPV6
|
((struct sockaddr_in *)&myipnum)->sin_port = 0;
|
||||||
if(theiripnum.ss_family == AF_INET6)
|
SET_SS_FAMILY(&myipnum, GET_SS_FAMILY(&server_p->my_ipnum));
|
||||||
((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
|
|
||||||
|
|
||||||
return serv_connect_resolved(client_p);
|
}
|
||||||
|
else if(GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET && ServerInfo.specific_ipv4_vhost)
|
||||||
|
{
|
||||||
|
memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum));
|
||||||
|
((struct sockaddr_in *)&myipnum)->sin_port = 0;
|
||||||
|
SET_SS_FAMILY(&myipnum, AF_INET);
|
||||||
|
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RB_IPV6
|
||||||
|
else if((GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET6) && ServerInfo.specific_ipv6_vhost)
|
||||||
|
{
|
||||||
|
memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
|
||||||
|
((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
|
||||||
|
SET_SS_FAMILY(&myipnum, AF_INET6);
|
||||||
|
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
|
||||||
|
}
|
||||||
|
#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
|
else
|
||||||
{
|
rb_connect_tcp(client_p->localClient->F,
|
||||||
#ifdef RB_IPV6
|
(struct sockaddr *)&server_p->my_ipnum, NULL, 0,
|
||||||
if(theiripnum.ss_family == AF_INET6)
|
serv_connect_callback, client_p,
|
||||||
((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
|
ConfigFileEntry.connect_timeout);
|
||||||
else
|
|
||||||
#endif
|
|
||||||
((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
|
|
||||||
|
|
||||||
client_p->localClient->dnsquery = rb_malloc(sizeof(struct DNSQuery));
|
|
||||||
client_p->localClient->dnsquery->ptr = client_p;
|
|
||||||
client_p->localClient->dnsquery->callback = serv_connect_dns_callback;
|
|
||||||
gethost_byname_type(server_p->host, client_p->localClient->dnsquery,
|
|
||||||
#ifdef RB_IPV6
|
|
||||||
server_p->aftype == AF_INET6 ? T_AAAA :
|
|
||||||
#endif
|
|
||||||
T_A);
|
|
||||||
return 1;
|
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);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue