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 Blacklist *blacklist;
|
||||
struct Client *client_p;
|
||||
struct DNSQuery dns_query;
|
||||
uint16_t dns_id;
|
||||
rb_dlink_node node;
|
||||
};
|
||||
|
||||
|
|
|
@ -236,8 +236,6 @@ struct LocalUser
|
|||
/* time challenge response is valid for */
|
||||
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 last;
|
||||
uint32_t connid;
|
||||
|
|
|
@ -41,7 +41,6 @@ struct Listener
|
|||
int ssl; /* ssl listener */
|
||||
int defer_accept; /* use TCP_DEFER_ACCEPT */
|
||||
struct rb_sockaddr_storage addr;
|
||||
struct DNSQuery *dns_query;
|
||||
char vhost[HOSTLEN + 1]; /* virtual name of listener */
|
||||
};
|
||||
|
||||
|
|
|
@ -193,6 +193,8 @@ struct server_conf
|
|||
char *class_name;
|
||||
struct Class *class;
|
||||
rb_dlink_node node;
|
||||
|
||||
uint16_t dns_query;
|
||||
};
|
||||
|
||||
#define SERVER_ILLEGAL 0x0001
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include "stdinc.h"
|
||||
#include "client.h"
|
||||
#include "res.h"
|
||||
#include "dns.h"
|
||||
#include "numeric.h"
|
||||
#include "reject.h"
|
||||
#include "s_conf.h"
|
||||
|
@ -60,27 +60,16 @@ static struct Blacklist *find_blacklist(char *name)
|
|||
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;
|
||||
char ipaddr[HOSTIPLEN];
|
||||
char *lastoctet;
|
||||
const char *lastoctet;
|
||||
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 */
|
||||
if (!rb_dlink_list_length(&blptr->filters))
|
||||
return 1;
|
||||
|
||||
rb_inet_ntop_sock((struct sockaddr *)addr, ipaddr, sizeof(ipaddr));
|
||||
|
||||
/* Below will prolly have to change too if the above changes */
|
||||
if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
|
||||
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)
|
||||
{
|
||||
struct BlacklistFilter *filter = ptr->data;
|
||||
char *cmpstr;
|
||||
const char *cmpstr;
|
||||
|
||||
if (filter->type == BLACKLIST_FILTER_ALL)
|
||||
cmpstr = ipaddr;
|
||||
|
@ -118,7 +107,7 @@ blwarn:
|
|||
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;
|
||||
int listed = 0;
|
||||
|
@ -134,9 +123,9 @@ static void blacklist_dns_callback(void *vptr, struct DNSReply *reply)
|
|||
return;
|
||||
}
|
||||
|
||||
if (reply != NULL)
|
||||
if (result != NULL && status)
|
||||
{
|
||||
if (blacklist_check_reply(blcptr, &reply->addr))
|
||||
if (blacklist_check_reply(blcptr, result))
|
||||
listed = TRUE;
|
||||
}
|
||||
|
||||
|
@ -167,9 +156,6 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
|
|||
blcptr->blacklist = blptr;
|
||||
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)
|
||||
{
|
||||
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
|
||||
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);
|
||||
blptr->refcount++;
|
||||
|
@ -297,7 +283,7 @@ void abort_blacklist_queries(struct Client *client_p)
|
|||
blcptr = ptr->data;
|
||||
rb_dlinkDelete(&blcptr->node, &client_p->preClient->dnsbl_queries);
|
||||
unref_blacklist(blcptr->blacklist);
|
||||
delete_resolver_queries(&blcptr->dns_query);
|
||||
cancel_lookup(blcptr->dns_id);
|
||||
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);
|
||||
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);
|
||||
|
||||
if(!IsIOError(source_p))
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "ircd.h"
|
||||
#include "numeric.h"
|
||||
#include "packet.h"
|
||||
#include "res.h"
|
||||
#include "dns.h"
|
||||
#include "logger.h"
|
||||
#include "s_stats.h"
|
||||
#include "send.h"
|
||||
|
@ -55,7 +55,7 @@ struct AuthRequest
|
|||
{
|
||||
rb_dlink_node node;
|
||||
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 */
|
||||
rb_fde_t *F; /* file descriptor for auth queries */
|
||||
time_t timeout; /* time when query expires */
|
||||
|
@ -198,7 +198,7 @@ release_auth_client(struct AuthRequest *auth)
|
|||
* of success of failure
|
||||
*/
|
||||
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;
|
||||
ClearDNSPending(auth);
|
||||
|
@ -216,50 +216,16 @@ auth_dns_callback(void *vptr, struct DNSReply *reply)
|
|||
return;
|
||||
}
|
||||
|
||||
if(reply)
|
||||
if(result != NULL && status)
|
||||
{
|
||||
int good = 1;
|
||||
|
||||
if(auth->client->localClient->ip.ss_family == AF_INET)
|
||||
if(good && strlen(result) <= HOSTLEN)
|
||||
{
|
||||
struct sockaddr_in *ip, *ip_fwd;
|
||||
|
||||
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));
|
||||
rb_strlcpy(auth->client->host, result, sizeof(auth->client->host));
|
||||
sendheader(auth->client, REPORT_FIN_DNS);
|
||||
}
|
||||
else if (strlen(reply->h_name) > HOSTLEN)
|
||||
else if (strlen(result) > HOSTLEN)
|
||||
sendheader(auth->client, REPORT_HOST_TOOLONG);
|
||||
}
|
||||
else
|
||||
|
@ -447,13 +413,10 @@ start_auth(struct Client *client)
|
|||
|
||||
auth = make_auth_request(client);
|
||||
|
||||
auth->dns_query.ptr = auth;
|
||||
auth->dns_query.callback = auth_dns_callback;
|
||||
|
||||
sendheader(client, REPORT_DO_DNS);
|
||||
|
||||
/* 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);
|
||||
|
||||
|
@ -493,7 +456,7 @@ timeout_auth_queries_event(void *notused)
|
|||
if(IsDNSPending(auth))
|
||||
{
|
||||
ClearDNSPending(auth);
|
||||
delete_resolver_queries(&auth->dns_query);
|
||||
cancel_lookup(auth->dns_id);
|
||||
sendheader(auth->client, REPORT_FAIL_DNS);
|
||||
}
|
||||
|
||||
|
@ -636,7 +599,7 @@ delete_auth_queries(struct Client *target_p)
|
|||
target_p->localClient->auth_request = NULL;
|
||||
|
||||
if(IsDNSPending(auth))
|
||||
delete_resolver_queries(&auth->dns_query);
|
||||
cancel_lookup(auth->dns_id);
|
||||
|
||||
if(auth->F != NULL)
|
||||
rb_close(auth->F);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "irc_dictionary.h"
|
||||
#include "s_assert.h"
|
||||
#include "logger.h"
|
||||
#include "dns.h"
|
||||
|
||||
rb_dlink_list shared_conf_list;
|
||||
rb_dlink_list cluster_conf_list;
|
||||
|
@ -354,6 +355,27 @@ free_server_conf(struct server_conf *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
|
||||
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");
|
||||
}
|
||||
|
||||
if(strchr(server_p->host, '*') || strchr(server_p->host, '?'))
|
||||
if(strpbrk(server_p->host, "*?"))
|
||||
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 *
|
||||
|
|
244
ircd/s_serv.c
244
ircd/s_serv.c
|
@ -971,139 +971,10 @@ server_estab(struct Client *client_p)
|
|||
* -- 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
|
||||
*
|
||||
* inputs - pointer to conf
|
||||
* inputs - pointer to conf
|
||||
* - pointer to client doing the connet
|
||||
* output -
|
||||
* side effects -
|
||||
|
@ -1121,14 +992,18 @@ int
|
|||
serv_connect(struct server_conf *server_p, struct Client *by)
|
||||
{
|
||||
struct Client *client_p;
|
||||
struct rb_sockaddr_storage theiripnum;
|
||||
rb_fde_t *F;
|
||||
struct rb_sockaddr_storage myipnum;
|
||||
char note[HOSTLEN + 10];
|
||||
rb_fde_t *F;
|
||||
|
||||
s_assert(server_p != NULL);
|
||||
if(server_p == NULL)
|
||||
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
|
||||
*/
|
||||
|
@ -1144,27 +1019,32 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
}
|
||||
|
||||
/* 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");
|
||||
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);
|
||||
|
||||
/* Create a local client */
|
||||
client_p = make_client(NULL);
|
||||
|
||||
/* Copy in the server, hostname, fd
|
||||
* The sockhost may be a hostname, this will be corrected later
|
||||
* -- jilles
|
||||
*/
|
||||
/* 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));
|
||||
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;
|
||||
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
|
||||
|
@ -1191,57 +1071,67 @@ serv_connect(struct server_conf *server_p, struct Client *by)
|
|||
* The socket has been connected or connect is in progress.
|
||||
*/
|
||||
make_server(client_p);
|
||||
if(by && IsPerson(by))
|
||||
{
|
||||
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++;
|
||||
}
|
||||
if(by && IsClient(by))
|
||||
strcpy(client_p->serv->by, by->name);
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
strcpy(client_p->serv->by, "AutoConn.");
|
||||
|
||||
SetConnecting(client_p);
|
||||
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));
|
||||
#ifdef RB_IPV6
|
||||
if(theiripnum.ss_family == AF_INET6)
|
||||
((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);
|
||||
memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
|
||||
((struct sockaddr_in *)&myipnum)->sin_port = 0;
|
||||
SET_SS_FAMILY(&myipnum, GET_SS_FAMILY(&server_p->my_ipnum));
|
||||
|
||||
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
|
||||
{
|
||||
#ifdef RB_IPV6
|
||||
if(theiripnum.ss_family == AF_INET6)
|
||||
((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
|
||||
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
|
||||
#endif
|
||||
((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
|
||||
rb_connect_tcp(client_p->localClient->F,
|
||||
(struct sockaddr *)&server_p->my_ipnum, NULL, 0,
|
||||
serv_connect_callback, client_p,
|
||||
ConfigFileEntry.connect_timeout);
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue