if (NULL == host) {
s->s.SetAnyAddr();
s->s.SetPort(port);
- debugs(3, 3, "http(s)_port: found Listen on wildcard address: " << s->s);
+ debugs(3, 3, "http(s)_port: found Listen on wildcard address: *:" << s->s.GetPort() );
} else if ( s->s = host ) { /* check/parse numeric IPA */
s->s.SetPort(port);
debugs(3, 3, "http(s)_port: Listen on Host/IP: " << host << " --> " << s->s);
add_http_port(char *portspec)
{
http_port_list *s = create_http_port(portspec);
+ // we may need to merge better of the above returns a list with clones
+ assert(s->next == NULL);
s->next = Config.Sockaddr.http;
Config.Sockaddr.http = s;
}
+#if IPV6_SPECIAL_SPLITSTACK
+http_port_list *
+clone_http_port_list(http_port_list *a)
+{
+ http_port_list *b = new http_port_list(a->protocol);
+
+ b->s = a->s;
+ if (a->name)
+ b->name = xstrdup(a->name);
+ if (a->defaultsite)
+ b->defaultsite = xstrdup(a->defaultsite);
+
+ b->intercepted = a->intercepted;
+ b->spoof_client_ip = a->spoof_client_ip;
+ b->accel = a->accel;
+ b->allow_direct = a->allow_direct;
+ b->vhost = a->vhost;
+ b->sslBump = a->sslBump;
+ b->vport = a->vport;
+ b->connection_auth_disabled = a->connection_auth_disabled;
+ b->disable_pmtu_discovery = a->disable_pmtu_discovery;
+
+ memcpy( &(b->tcp_keepalive), &(a->tcp_keepalive), sizeof(a->tcp_keepalive));
+
+#if 0
+ // AYJ: 2009-07-18: for now SSL does not clone. Configure separate ports with IPs and SSL settings
+
+#if USE_SSL
+ // XXX: temporary hack to ease move of SSL options to http_port
+ http_port_list &http;
+
+ char *cert;
+ char *key;
+ int version;
+ char *cipher;
+ char *options;
+ char *clientca;
+ char *cafile;
+ char *capath;
+ char *crlfile;
+ char *dhfile;
+ char *sslflags;
+ char *sslcontext;
+ SSL_CTX *sslContext;
+#endif
+
+#endif /*0*/
+
+ return b;
+}
+#endif
+
static void
parse_http_port_list(http_port_list ** head)
{
parse_http_port_option(s, token);
}
+#if IPV6_SPECIAL_SPLITSTACK
+ if (s->s.IsAnyAddr()) {
+ // clone the port options from *s to *(s->next)
+ s->next = clone_http_port_list(s);
+ s->next->s.SetIPv4();
+ debugs(3, 3, "http(s)_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s);
+ }
+#endif
+
while (*head)
head = &(*head)->next;
if (F->local_addr.GetPort())
return F->local_addr.GetPort();
+#if USE_IPV6
+ if (F->sock_family == AF_INET)
+ temp.SetIPv4();
+#endif
+
temp.InitAddrInfo(addr);
if (getsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) {
F->local_addr.SetPort(temp.GetPort());
+#if 0 // seems to undo comm_open actions on the FD ...
// grab default socket information for this address
temp.GetAddrInfo(addr);
F->sock_family = addr->ai_family;
temp.FreeAddrInfo(addr);
+#endif
- debugs(5, 6, "comm_local_port: FD " << fd << ": port " << F->local_addr.GetPort());
+ debugs(5, 6, "comm_local_port: FD " << fd << ": port " << F->local_addr.GetPort() << "(family=" << F->sock_family << ")");
return F->local_addr.GetPort();
}
{
#ifdef IPV6_V6ONLY
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tos, sizeof(int)) < 0) {
- debugs(50, 1, "comm_open: setsockopt(IPV6_V6ONLY) on FD " << fd << ": " << xstrerror());
+ debugs(50, 1, "comm_open: setsockopt(IPV6_V6ONLY) " << (tos?"ON":"OFF") << " for FD " << fd << ": " << xstrerror());
}
#else
debugs(50, 0, "WARNING: comm_open: setsockopt(IPV6_V6ONLY) not supported on this platform");
#if IPV6_SPECIAL_SPLITSTACK
if ( addr.IsIPv6() )
- comm_set_v6only(new_socket, tos);
+ comm_set_v6only(new_socket, 1);
#endif
debugs(50, 3, "commResetFD: Reset socket FD " << fd << "->" << fd2 << " : family=" << new_family );
+ debugs(50, 3, "commResetFD: Reset socket FD " << fd << "->" << fd2 << " : family=" << new_family );
+
/* INET6: copy the new sockets family type to the FDE table */
F->sock_family = new_family;
comm_set_tos(fd, F->tos);
#if IPV6_SPECIAL_SPLITSTACK
-
if ( F->local_addr.IsIPv6() )
- comm_set_v6only(fd, F->tos);
-
+ comm_set_v6only(fd, 1);
#endif
copyFDFlags(fd, F);
static void
idnsSendQuery(idns_query * q)
{
- int x;
- int ns;
-
- if (DnsSocket < 0) {
+ if (DnsSocketA < 0 && DnsSocketB < 0) {
debugs(78, 1, "WARNING: idnsSendQuery: Can't send query, no DNS socket!");
return;
}
assert(q->lru.prev == NULL);
+ int x = -1, y = -1;
+ int ns;
+
do {
ns = q->nsends % nns;
if (q->need_vc) {
idnsSendQueryVC(q, ns);
- x = 0;
+ x = y = 0;
} else {
- x = comm_udp_sendto(DnsSocket, nameservers[ns].S, q->buf, q->sz);
+#if IPV6_SPECIAL_SPLITSTACK
+ if (nameservers[ns].S.IsIPv6() && DnsSocketB > 0)
+ y = comm_udp_sendto(DnsSocketB, nameservers[ns].S, q->buf, q->sz);
+ else
+#endif
+ x = comm_udp_sendto(DnsSocketA, nameservers[ns].S, q->buf, q->sz);
}
q->nsends++;
q->queue_t = q->sent_t = current_time;
+#if IPV6_SPECIAL_SPLITSTACK
+ if (y < 0 && nameservers[ns].S.IsIPv6())
+ debugs(50, 1, "idnsSendQuery: FD " << DnsSocketB << ": sendto: " << xstrerror());
+ if (x < 0 && nameservers[ns].S.IsIPv4())
+#else
if (x < 0)
- debugs(50, 1, "idnsSendQuery: FD " << DnsSocket << ": sendto: " << xstrerror());
+#endif
+ debugs(50, 1, "idnsSendQuery: FD " << DnsSocketA << ": sendto: " << xstrerror());
- } while ( x<0 && q->nsends % nns != 0);
+ } while ( (x<0 && y<0) && q->nsends % nns != 0);
+
+#if IPV6_SPECIAL_SPLITSTACK
+ if (y >= 0) {
+ fd_bytes(DnsSocketB, y, FD_WRITE);
+ commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
+ }
+#endif
if (x >= 0) {
- fd_bytes(DnsSocket, x, FD_WRITE);
- commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
+ fd_bytes(DnsSocketA, x, FD_WRITE);
+ commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
}
nameservers[ns].nqueries++;
break;
}
- fd_bytes(DnsSocket, len, FD_READ);
+#if IPV6_SPECIAL_SPLITSTACK
+ if ( from.IsIPv6() )
+ fd_bytes(DnsSocketB, len, FD_READ);
+ else
+#endif
+ fd_bytes(DnsSocketA, len, FD_READ);
+
assert(N);
(*N)++;
idnsGrokReply(rbuf, len);
}
- if (lru_list.head)
- commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
+ if (lru_list.head) {
+#if IPV6_SPECIAL_SPLITSTACK
+ if ( from.IsIPv6() )
+ commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
+ else
+#endif
+ commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
+ }
}
static void
CBDATA_INIT_TYPE(nsvc);
CBDATA_INIT_TYPE(idns_query);
- if (DnsSocket < 0) {
+ if (DnsSocketA < 0 && DnsSocketB < 0) {
int port;
IpAddress addr; // since we don't want to alter Config.Addrs.udp_* and dont have one of our own.
else
addr = Config.Addrs.udp_incoming;
+#if IPV6_SPECIAL_SPLITSTACK
+ IpAddress addr4 = addr;
+
+ if ( addr.IsAnyAddr() || addr.IsIPv6() ) {
+ debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
+ DnsSocketB = comm_open_listener(SOCK_DGRAM,
+ IPPROTO_UDP,
+ addr,
+ COMM_NONBLOCKING,
+ "DNS Socket v6");
+ }
+
+ if ( addr.IsAnyAddr() || addr.IsIPv4() ) {
+ addr4.SetIPv4();
+ debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr4);
+ DnsSocketA = comm_open_listener(SOCK_DGRAM,
+ IPPROTO_UDP,
+ addr4,
+ COMM_NONBLOCKING,
+ "DNS Socket v4");
+ }
+#else
+ DnsSocketA = comm_open_listener(SOCK_DGRAM,
+ IPPROTO_UDP,
+ addr,
+ COMM_NONBLOCKING,
+ "DNS Socket");
debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
- DnsSocket = comm_open_listener(SOCK_DGRAM,
- IPPROTO_UDP,
- addr,
- COMM_NONBLOCKING,
- "DNS Socket");
+#endif
- if (DnsSocket < 0)
+ if (DnsSocketA < 0 && DnsSocketB < 0)
fatal("Could not create a DNS socket");
/* Ouch... we can't call functions using debug from a debug
* statement. Doing so messes up the internal Debug::level
*/
- port = comm_local_port(DnsSocket);
-
- debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocket);
+#if IPV6_SPECIAL_SPLITSTACK
+ if (DnsSocketB >= 0) {
+ port = comm_local_port(DnsSocketB);
+ debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocketB);
+ }
+#endif
+ if (DnsSocketA >= 0) {
+ port = comm_local_port(DnsSocketA);
+#if IPV6_SPECIAL_SPLITSTACK
+ debugs(78, 1, "DNS Socket created at " << addr4 << ", FD " << DnsSocketA);
+#else
+ debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocketA);
+#endif
+ }
}
assert(0 == nns);
void
idnsShutdown(void)
{
- if (DnsSocket < 0)
+ if (DnsSocketA < 0 && DnsSocketB < 0)
return;
- comm_close(DnsSocket);
+ if (DnsSocketA >= 0 ) {
+ comm_close(DnsSocketA);
+ DnsSocketA = -1;
+ }
- DnsSocket = -1;
+#if IPV6_SPECIAL_SPLITSTACK
+ if (DnsSocketA >= 0 ) {
+ comm_close(DnsSocketB);
+ DnsSocketB = -1;
+ }
+#endif
for (int i = 0; i < nns; i++) {
if (nsvc *vc = nameservers[i].vc) {
}
idnsFreeNameservers();
-
idnsFreeSearchpath();
}