* -- 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",
+ get_server_name(client_p, HIDE_IP));
+ 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(myipnum));
+ ((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(myipnum));
+ ((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(myipnum));
+ ((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" : "?"));
+
+ 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 */
+ inetntop_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);
+
+
+ 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",
+ get_server_name(client_p, HIDE_IP));
+ 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 */
+ inetntop_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(struct server_conf *server_p, struct Client *by)
{
struct Client *client_p;
- struct rb_sockaddr_storage myipnum, theiripnum;
+ struct rb_sockaddr_storage theiripnum;
rb_fde_t *F;
- char vhoststr[HOSTIPLEN];
char note[HOSTLEN + 10];
s_assert(server_p != NULL);
return 0;
}
- if (rb_inet_pton_sock(server_p->host, (struct sockaddr *)&theiripnum) <= 0)
- {
- sendto_realops_snomask(SNO_GENERAL, L_ALL,
- "Server %s host is a DNS name which is currently not implemented",
- server_p->name);
- if(by && IsPerson(by) && !MyClient(by))
- sendto_one_notice(by, ":Server %s host is a DNS name which is currently not implemented",
- server_p->name);
- return 0;
- }
-
-#ifdef RB_IPV6
- if(theiripnum.ss_family == AF_INET6)
- ((struct sockaddr_in6 *)&theiripnum)->sin6_port = htons(server_p->port);
- else
-#endif
- ((struct sockaddr_in *)&theiripnum)->sin_port = htons(server_p->port);
-
/* create a socket for the server connection */
if((F = rb_socket(server_p->aftype, SOCK_STREAM, 0, NULL)) == NULL)
{
strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
strlcpy(client_p->sockhost, server_p->host, sizeof(client_p->sockhost));
- memcpy(&client_p->localClient->ip, &theiripnum, sizeof(client_p->localClient->ip));
client_p->localClient->F = F;
/*
SetConnecting(client_p);
rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
- if(ServerConfVhosted(server_p))
+ if (rb_inet_pton_sock(server_p->host, (struct sockaddr *)&theiripnum) > 0)
{
- memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
- ((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(myipnum));
- ((struct sockaddr_in *)&myipnum)->sin_port = 0;
- myipnum.ss_family = AF_INET;
- SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
- }
-
+ memcpy(&client_p->localClient->ip, &theiripnum, sizeof(client_p->localClient->ip));
#ifdef RB_IPV6
- else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost)
- {
- memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
- ((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
- myipnum.ss_family = AF_INET6;
- SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
- }
+ 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);
+
+ return serv_connect_resolved(client_p);
+ }
else
{
- /* log */
- ilog(L_SERVER, "Connecting to %s[%s] port %d (%s)", server_p->name, server_p->host, server_p->port,
#ifdef RB_IPV6
- server_p->aftype == AF_INET6 ? "IPv6" :
+ if(theiripnum.ss_family == AF_INET6)
+ ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
+ else
#endif
- (server_p->aftype == AF_INET ? "IPv4" : "?"));
-
- rb_connect_tcp(client_p->localClient->F,
- (struct sockaddr *) &theiripnum,
- NULL, 0,
- serv_connect_callback, client_p,
- ConfigFileEntry.connect_timeout);
- return 1;
- }
+ ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
- /* log */
- inetntop_sock((struct sockaddr *)&myipnum, vhoststr, sizeof vhoststr);
- ilog(L_SERVER, "Connecting to %s[%s] port %d (%s) (vhost %s)", server_p->name, server_p->host, 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 ? "IPv6" :
+ server_p->aftype == AF_INET6 ? T_AAAA :
#endif
- (server_p->aftype == AF_INET ? "IPv4" : "?"), vhoststr);
-
-
- rb_connect_tcp(client_p->localClient->F,
- (struct sockaddr *) &theiripnum,
- (struct sockaddr *) &myipnum, GET_SS_LEN(&myipnum),
- serv_connect_callback, client_p,
- ConfigFileEntry.connect_timeout);
-
- return 1;
+ T_A);
+ return 1;
+ }
}
/*
return;
}
-#if 0
- /* Next, for backward purposes, record the ip of the server */
- memcpy(&client_p->localClient->ip, &F->connect.hostaddr, sizeof client_p->localClient->ip);
- /* Set sockhost properly now -- jilles */
- inetntop_sock((struct sockaddr *)&F->connect.hostaddr,
- client_p->sockhost, sizeof client_p->sockhost);
-#endif
-
/* Check the status */
if(status != RB_OK)
{