enter_suid();
if (s->spoof_client_ip) {
- fd = comm_openex(SOCK_STREAM, IPPROTO_TCP, s->s, (COMM_NONBLOCKING|COMM_TRANSPARENT), 0, "HTTP Socket");
+ fd = comm_open_listener(SOCK_STREAM, IPPROTO_TCP, s->s, (COMM_NONBLOCKING|COMM_TRANSPARENT), "HTTP Socket");
} else {
- fd = comm_open(SOCK_STREAM, IPPROTO_TCP, s->s, COMM_NONBLOCKING, "HTTP Socket");
+ fd = comm_open_listener(SOCK_STREAM, IPPROTO_TCP, s->s, COMM_NONBLOCKING, "HTTP Socket");
}
leave_suid();
}
enter_suid();
- fd = comm_open(SOCK_STREAM,
+ fd = comm_open_listener(SOCK_STREAM,
IPPROTO_TCP,
s->http.s,
COMM_NONBLOCKING, "HTTPS Socket");
return comm_openex(sock_type, proto, addr, flags, 0, note);
}
+int
+comm_open_listener(int sock_type,
+ int proto,
+ IpAddress &addr,
+ int flags,
+ const char *note)
+{
+ int sock = -1;
+
+ /* attempt native enabled port. */
+ sock = comm_openex(sock_type, proto, addr, flags, 0, note);
+
+#if USE_IPV6
+ /* under IPv6 there is the possibility IPv6 is present but disabled. */
+ /* try again as IPv4-native */
+ if ( sock < 0 && addr.IsIPv6() && addr.SetIPv4() ) {
+ /* attempt to open this IPv4-only. */
+ sock = comm_openex(sock_type, proto, addr, flags, 0, note);
+ debugs(50, 2, HERE << "attempt open " << note << " socket on: " << addr);
+ }
+#endif
+
+ return sock;
+}
+
static bool
limitError(int const anErrno)
{
SQUIDCEXTERN int comm_open(int, int, IpAddress &, int, const char *note);
+/**
+ * Open a port specially bound for listening or sending through a specific port.
+ * This is a wrapper providing IPv4/IPv6 failover around comm_openex().
+ * Please use for all listening sockets and bind() outbound sockets.
+ *
+ * It will open a socket bound for:
+ * - IPv4 if IPv6 is disabled or address is IPv4-native.
+ * - IPv6 if address is IPv6-native
+ * - IPv6 dual-stack mode if able to open [::]
+ *
+ * When an open performs failover it update the given address to feedback
+ * the new IPv4-only status of the socket. Further displays of the IP
+ * (in debugs or cachemgr) will occur in Native IPv4 format.
+ * A reconfigure is needed to reset the stored IP in most cases and attempt a port re-open.
+ */
+SQUIDCEXTERN int comm_open_listener(int sock_type, int proto, IpAddress &addr, int flags, const char *note);
+
SQUIDCEXTERN int comm_openex(int, int, IpAddress &, int, unsigned char TOS, const char *);
SQUIDCEXTERN u_short comm_local_port(int fd);
SQUIDCEXTERN int comm_set_tos(int fd, int tos);
if (DnsSocket < 0) {
int port;
- IpAddress addr;
+ IpAddress addr; // since we don't want to alter Config.Addrs.udp_* and dont have one of our own.
if (!Config.Addrs.udp_outgoing.IsNoAddr())
addr = Config.Addrs.udp_outgoing;
else
addr = Config.Addrs.udp_incoming;
- DnsSocket = comm_open(SOCK_DGRAM,
+ debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
+ DnsSocket = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
addr,
COMM_NONBLOCKING,
"DNS Socket");
- debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
-
-#if USE_IPV6
- if ( DnsSocket < 0 && addr.IsIPv6() && addr.SetIPv4() ) {
- /* attempt to open this IPv4-only. */
- DnsSocket = comm_open(SOCK_DGRAM,
- IPPROTO_UDP,
- addr,
- COMM_NONBLOCKING,
- "DNS Socket");
-
- debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
- }
-#endif
-
if (DnsSocket < 0)
fatal("Could not create a DNS socket");
incomingAddr.SetPort(Config.Port.htcp);
enter_suid();
- htcpInSocket = comm_open(SOCK_DGRAM,
+ htcpInSocket = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
incomingAddr,
COMM_NONBLOCKING,
outgoingAddr.SetPort(Config.Port.htcp);
enter_suid();
- htcpOutSocket = comm_open(SOCK_DGRAM,
+ htcpOutSocket = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
outgoingAddr,
COMM_NONBLOCKING,
addr = Config.Addrs.udp_incoming;
addr.SetPort(port);
- theInIcpConnection = comm_open(SOCK_DGRAM,
+ theInIcpConnection = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
addr,
COMM_NONBLOCKING,
if ( !addr.IsNoAddr() ) {
enter_suid();
addr.SetPort(port);
- theOutIcpConnection = comm_open(SOCK_DGRAM,
+ theOutIcpConnection = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
addr,
COMM_NONBLOCKING,
return;
}
- fd = comm_open(SOCK_STREAM,
+ fd = comm_open_listener(SOCK_STREAM,
IPPROTO_TCP,
me,
COMM_NONBLOCKING,
if (Config.Port.snmp > 0) {
Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp);
enter_suid();
- theInSnmpConnection = comm_open(SOCK_DGRAM,
+ theInSnmpConnection = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
Config.Addrs.snmp_incoming,
COMM_NONBLOCKING,
leave_suid();
if (theInSnmpConnection < 0)
- fatal("Cannot open snmp Port");
+ fatal("Cannot open SNMP Port");
commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
if (!Config.Addrs.snmp_outgoing.IsNoAddr()) {
Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp);
enter_suid();
- theOutSnmpConnection = comm_open(SOCK_DGRAM,
+ theOutSnmpConnection = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
Config.Addrs.snmp_outgoing,
COMM_NONBLOCKING,
Config.Wccp.address.SetPort(WCCP_PORT);
- theWccpConnection = comm_open(SOCK_DGRAM,
+ theWccpConnection = comm_open_listener(SOCK_DGRAM,
IPPROTO_UDP,
Config.Wccp.address,
COMM_NONBLOCKING,
}
Config.Wccp2.address.SetPort(WCCP_PORT);
- theWccp2Connection = comm_open(SOCK_DGRAM,
+ theWccp2Connection = comm_open_listener(SOCK_DGRAM,
0,
Config.Wccp2.address,
COMM_NONBLOCKING,