Hello again,

a few days ago I described the following situation and problem, 
where I am now able to provide a solution for:

> At least I would like a configurable option for the outgoing address
> in dependence of the destination sibling, to suite the following
> scenario:
> 
> At two locations are running two (or even more) proxies with the 
> following (sample) configuration:
> 
> Interface     Location A      Location B
> 
> le0           192.168.1.2     192.168.1.130
> le0:1         192.168.1.4     (192.168.1.4)
> le0:2         (192.168.1.132) 192.168.1.132
> 
> The official proxy addresses are .4 and .132 and they are load balanced 
> by DNS Round Robin.
> In the normal case the load is also balanced over the two machines. But
> in case of a failure of one machine (or location) the other location
> will become active and responsible for the failed IP-address.
> 
> Because we don't want to announce the hard adresses to our customers,
> the proxies have to be configured with udp_outgoing_address
> .4 for location A and .132 for location B to be usefull two other
> proxies as parents or siblings. (Otherwise the siblings running with
> older squid versions will not receive or ignore the response, coming
> from an unexpected ip-address).
> 
To express in other words: a neighbor/peer request from Location A will 
always have the source address 192.168.1.4. So the response from
Location B will go to this address, which itself is configured there.
So the response will never go to Location A :-(

To fix this problem I created a new option: udp_outgoing_peer
If you're using this option, every neighbor requests are routed over this
IP-address instead of the default one (udp_outgoing_address).

For this I created a new fd 'thePeerIcpConnection' within the source, 
and changed all relevant calls to use this fd.
(The fd is copied from 'theOutIcpConnection' if you're not using the
new option and would then cause no behavioral changes.)

The patch is included below; It should be usefull for others with an
equal redundant setup as we have and maybe so for similar ones.
If so, it may/should go into the distribution.

Enjoy,
        Jan
Only in squid-2.2.peer/src: Makefile
Only in squid-2.2.peer/src: TAGS
diff -cr squid-2.2.DEVEL3/src/cf.data.pre squid-2.2.peer/src/cf.data.pre
*** squid-2.2.DEVEL3/src/cf.data.pre	Wed Feb 10 00:10:31 1999
--- squid-2.2.peer/src/cf.data.pre	Sun Apr  4 10:50:34 1999
***************
*** 151,159 ****
--- 151,166 ----
  TYPE: address
  LOC: Config.Addrs.udp_outgoing
  DEFAULT: 255.255.255.255
+ DOC_NONE
+ 
+ NAME: udp_outgoing_peer
+ TYPE: address
+ LOC: Config.Addrs.udp_out_peer
+ DEFAULT: 255.255.255.255
  DOC_START
  	Usage: tcp_incoming_address 10.20.30.40
  	       udp_outgoing_address fully.qualified.domain.name
+ 	       udp_outgoing_peer    10.20.30.33
  
  	tcp_incoming_address	is used for the HTTP socket which accepts
  				connections from clients and other caches.
***************
*** 163,168 ****
--- 170,177 ----
  				from other caches.
  	udp_outgoing_address	is used for ICP packets sent out to other
  				caches.
+ 	udp_outgoing_peer	is used for ICP packets sent to configured
+ 				peers. (usually hard interface eth0 or le0)
  
  	The default behaviour is to not bind to any specific address.
  
***************
*** 174,179 ****
--- 183,189 ----
  tcp_outgoing_address 0.0.0.0
  udp_incoming_address 0.0.0.0
  udp_outgoing_address 0.0.0.0
+ udp_outgoing_peer    0.0.0.0
  DOC_END
  
  COMMENT_START
diff -cr squid-2.2.DEVEL3/src/comm_select.c squid-2.2.peer/src/comm_select.c
*** squid-2.2.DEVEL3/src/comm_select.c	Mon Jan 18 23:23:33 1999
--- squid-2.2.peer/src/comm_select.c	Sun Apr  4 11:12:45 1999
***************
*** 144,149 ****
--- 144,151 ----
  	return 1;
      if (fd == theOutIcpConnection)
  	return 1;
+     if (fd == thePeerIcpConnection)
+ 	return 1;
      return 0;
  }
  
***************
*** 223,230 ****
      if (theInIcpConnection >= 0)
  	fds[nfds++] = theInIcpConnection;
      if (theInIcpConnection != theOutIcpConnection)
! 	if (theOutIcpConnection >= 0)
  	    fds[nfds++] = theOutIcpConnection;
      if (nfds == 0)
  	return;
      nevents = comm_check_incoming_poll_handlers(nfds, fds);
--- 225,235 ----
      if (theInIcpConnection >= 0)
  	fds[nfds++] = theInIcpConnection;
      if (theInIcpConnection != theOutIcpConnection)
!         if (theOutIcpConnection >= 0) {
  	    fds[nfds++] = theOutIcpConnection;
+ 	    if (thePeerIcpConnection != theOutIcpConnection)
+ 	      fds[nfds++] = thePeerIcpConnection;
+ 	}
      if (nfds == 0)
  	return;
      nevents = comm_check_incoming_poll_handlers(nfds, fds);
***************
*** 487,494 ****
      if (theInIcpConnection >= 0)
  	fds[nfds++] = theInIcpConnection;
      if (theInIcpConnection != theOutIcpConnection)
! 	if (theOutIcpConnection >= 0)
  	    fds[nfds++] = theOutIcpConnection;
      if (nfds == 0)
  	return;
      nevents = comm_check_incoming_select_handlers(nfds, fds);
--- 492,502 ----
      if (theInIcpConnection >= 0)
  	fds[nfds++] = theInIcpConnection;
      if (theInIcpConnection != theOutIcpConnection)
!         if (theOutIcpConnection >= 0) {
  	    fds[nfds++] = theOutIcpConnection;
+ 	    if (thePeerIcpConnection != theOutIcpConnection)
+ 	      fds[nfds++] = thePeerIcpConnection;
+ 	}
      if (nfds == 0)
  	return;
      nevents = comm_check_incoming_select_handlers(nfds, fds);
diff -cr squid-2.2.DEVEL3/src/globals.h squid-2.2.peer/src/globals.h
*** squid-2.2.DEVEL3/src/globals.h	Fri Feb 12 23:32:17 1999
--- squid-2.2.peer/src/globals.h	Sat Apr  3 20:33:34 1999
***************
*** 92,97 ****
--- 92,98 ----
  extern int syslog_enable;	/* 0 */
  extern int theInIcpConnection;	/* -1 */
  extern int theOutIcpConnection;	/* -1 */
+ extern int thePeerIcpConnection;	/* -1 */
  #ifdef SQUID_SNMP
  extern int theInSnmpConnection;	/* -1 */
  extern int theOutSnmpConnection;	/* -1 */
***************
*** 105,110 ****
--- 106,112 ----
  extern struct in_addr local_addr;
  extern struct in_addr no_addr;
  extern struct in_addr theOutICPAddr;
+ extern struct in_addr thePeerICPAddr;
  extern struct in_addr theOutSNMPAddr;
  extern struct timeval current_time;
  extern struct timeval squid_start;
diff -cr squid-2.2.DEVEL3/src/icp_v2.c squid-2.2.peer/src/icp_v2.c
*** squid-2.2.DEVEL3/src/icp_v2.c	Fri Jan 29 22:28:13 1999
--- squid-2.2.peer/src/icp_v2.c	Sun Apr  4 11:30:12 1999
***************
*** 114,119 ****
--- 114,150 ----
      return buf;
  }
  
+ void *
+ icpPeerCreateMessage(
+     icp_opcode opcode,
+     int flags,
+     const char *url,
+     int reqnum,
+     int pad)
+ {
+     char *buf = NULL;
+     icp_common_t *headerp = NULL;
+     char *urloffset = NULL;
+     int buf_len;
+     buf_len = sizeof(icp_common_t) + strlen(url) + 1;
+     if (opcode == ICP_QUERY)
+ 	buf_len += sizeof(u_num32);
+     buf = xcalloc(buf_len, 1);
+     headerp = (icp_common_t *) (void *) buf;
+     headerp->opcode = (char) opcode;
+     headerp->version = ICP_VERSION_CURRENT;
+     headerp->length = (u_short) htons(buf_len);
+     headerp->reqnum = htonl(reqnum);
+     headerp->flags = htonl(flags);
+     headerp->pad = htonl(pad);
+     headerp->shostid = thePeerICPAddr.s_addr;
+     urloffset = buf + sizeof(icp_common_t);
+     if (opcode == ICP_QUERY)
+ 	urloffset += sizeof(u_num32);
+     xmemcpy(urloffset, url, strlen(url));
+     return buf;
+ }
+ 
  int
  icpUdpSend(int fd,
      const struct sockaddr_in *to,
***************
*** 456,461 ****
--- 487,526 ----
  	    theOutIcpConnection, xstrerror());
      else
  	theOutICPAddr = xaddr.sin_addr;
+ 
+     if (  (addr = Config.Addrs.udp_out_peer).s_addr != no_addr.s_addr
+ 	&& addr.s_addr != Config.Addrs.udp_outgoing.s_addr) {
+ 	enter_suid();
+ 	thePeerIcpConnection = comm_open(SOCK_DGRAM,
+ 	    0,
+ 	    addr,
+ 	    port,
+ 	    COMM_NONBLOCKING,
+ 	    "ICP Port");
+ 	leave_suid();
+ 	if (thePeerIcpConnection < 0)
+ 	    fatal("Cannot open Outgoing Peer ICP Port");
+ 	commSetSelect(thePeerIcpConnection,
+ 	    COMM_SELECT_READ,
+ 	    icpHandleUdp,
+ 	    NULL,
+ 	    0);
+ 	debug(12, 1) ("Outgoing Peer ICP messages on port %d, FD %d.\n",
+ 	    (int) port, thePeerIcpConnection);
+ 	fd_note(thePeerIcpConnection, "Outgoing Peer ICP socket");
+     } else {
+ 	thePeerIcpConnection = theOutIcpConnection;
+     }
+     memset(&thePeerICPAddr, '\0', sizeof(struct in_addr));
+     len = sizeof(struct sockaddr_in);
+     memset(&xaddr, '\0', len);
+     x = getsockname(thePeerIcpConnection,
+ 	(struct sockaddr *) &xaddr, &len);
+     if (x < 0)
+ 	debug(50, 1) ("thePeerIcpConnection FD %d: getsockname: %s\n",
+ 	    thePeerIcpConnection, xstrerror());
+     else
+ 	thePeerICPAddr = xaddr.sin_addr;
  }
  
  /*
***************
*** 486,491 ****
--- 551,558 ----
       */
      assert(theOutIcpConnection > -1);
      commSetSelect(theOutIcpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+     assert(thePeerIcpConnection > -1);
+     commSetSelect(thePeerIcpConnection, COMM_SELECT_READ, NULL, NULL, 0);
  }
  
  void
***************
*** 495,500 ****
--- 562,573 ----
      if (theOutIcpConnection > -1) {
  	debug(12, 1) ("FD %d Closing ICP connection\n", theOutIcpConnection);
  	comm_close(theOutIcpConnection);
+ 	if (thePeerIcpConnection != theOutIcpConnection) {
+ 	  debug(12, 1) ("FD %d Closing Peer ICP connection\n", 
+ 			thePeerIcpConnection);
+ 	  comm_close(thePeerIcpConnection);
+ 	  thePeerIcpConnection = -1;
+ 	}
  	theOutIcpConnection = -1;
      }
  }
diff -cr squid-2.2.DEVEL3/src/main.c squid-2.2.peer/src/main.c
*** squid-2.2.DEVEL3/src/main.c	Sun Jan 24 05:03:52 1999
--- squid-2.2.peer/src/main.c	Sat Apr  3 22:59:39 1999
***************
*** 333,341 ****
      redirectInit();
      authenticateInit();
      serverConnectionsOpen();
!     if (theOutIcpConnection >= 0) {
  	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
! 	    neighbors_open(theOutIcpConnection);
  	else
  	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
      }
--- 333,341 ----
      redirectInit();
      authenticateInit();
      serverConnectionsOpen();
!     if (thePeerIcpConnection >= 0) {
  	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
! 	    neighbors_open(thePeerIcpConnection);
  	else
  	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
      }
***************
*** 450,458 ****
  	fwdInit();
      }
      serverConnectionsOpen();
!     if (theOutIcpConnection >= 0) {
  	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
! 	    neighbors_open(theOutIcpConnection);
  	else
  	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
      }
--- 450,458 ----
  	fwdInit();
      }
      serverConnectionsOpen();
!     if (thePeerIcpConnection >= 0) {
  	if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
! 	    neighbors_open(thePeerIcpConnection);
  	else
  	    debug(1, 1) ("ICP port disabled in httpd_accelerator mode\n");
      }
diff -cr squid-2.2.DEVEL3/src/neighbors.c squid-2.2.peer/src/neighbors.c
*** squid-2.2.DEVEL3/src/neighbors.c	Fri Feb 12 22:41:51 1999
--- squid-2.2.peer/src/neighbors.c	Sun Apr  4 11:02:36 1999
***************
*** 374,380 ****
  
      if (Config.peers == NULL)
  	return 0;
!     if (theOutIcpConnection < 0)
  	fatal("neighborsUdpPing: There is no ICP socket!");
      assert(entry->swap_status == SWAPOUT_NONE);
      mem->start_ping = current_time;
--- 374,380 ----
  
      if (Config.peers == NULL)
  	return 0;
!     if (thePeerIcpConnection < 0)
  	fatal("neighborsUdpPing: There is no ICP socket!");
      assert(entry->swap_status == SWAPOUT_NONE);
      mem->start_ping = current_time;
***************
*** 392,398 ****
  	debug(15, 4) ("neighborsUdpPing: pinging peer %s for '%s'\n",
  	    p->host, url);
  	if (p->type == PEER_MULTICAST)
! 	    mcastSetTtl(theOutIcpConnection, p->mcast.ttl);
  	debug(15, 3) ("neighborsUdpPing: key = '%s'\n", storeKeyText(entry->key));
  	debug(15, 3) ("neighborsUdpPing: reqnum = %d\n", reqnum);
  
--- 392,398 ----
  	debug(15, 4) ("neighborsUdpPing: pinging peer %s for '%s'\n",
  	    p->host, url);
  	if (p->type == PEER_MULTICAST)
! 	    mcastSetTtl(thePeerIcpConnection, p->mcast.ttl);
  	debug(15, 3) ("neighborsUdpPing: key = '%s'\n", storeKeyText(entry->key));
  	debug(15, 3) ("neighborsUdpPing: reqnum = %d\n", reqnum);
  
***************
*** 405,412 ****
  	if (p->icp.port == echo_port) {
  	    debug(15, 4) ("neighborsUdpPing: Looks like a dumb cache, send DECHO ping\n");
  	    echo_hdr.reqnum = reqnum;
! 	    query = icpCreateMessage(ICP_DECHO, 0, url, reqnum, 0);
! 	    icpUdpSend(theOutIcpConnection,
  		&p->in_addr,
  		query,
  		LOG_ICP_QUERY,
--- 405,412 ----
  	if (p->icp.port == echo_port) {
  	    debug(15, 4) ("neighborsUdpPing: Looks like a dumb cache, send DECHO ping\n");
  	    echo_hdr.reqnum = reqnum;
! 	    query = icpPeerCreateMessage(ICP_DECHO, 0, url, reqnum, 0);
! 	    icpUdpSend(thePeerIcpConnection,
  		&p->in_addr,
  		query,
  		LOG_ICP_QUERY,
***************
*** 416,423 ****
  	    if (Config.onoff.query_icmp)
  		if (p->icp.version == ICP_VERSION_2)
  		    flags |= ICP_FLAG_SRC_RTT;
! 	    query = icpCreateMessage(ICP_QUERY, flags, url, reqnum, 0);
! 	    icpUdpSend(theOutIcpConnection,
  		&p->in_addr,
  		query,
  		LOG_ICP_QUERY,
--- 416,423 ----
  	    if (Config.onoff.query_icmp)
  		if (p->icp.version == ICP_VERSION_2)
  		    flags |= ICP_FLAG_SRC_RTT;
! 	    query = icpPeerCreateMessage(ICP_QUERY, flags, url, reqnum, 0);
! 	    icpUdpSend(thePeerIcpConnection,
  		&p->in_addr,
  		query,
  		LOG_ICP_QUERY,
***************
*** 488,495 ****
  		to_addr.sin_family = AF_INET;
  		to_addr.sin_addr = ia->in_addrs[ia->cur];
  		to_addr.sin_port = htons(echo_port);
! 		query = icpCreateMessage(ICP_SECHO, 0, url, reqnum, 0);
! 		icpUdpSend(theOutIcpConnection,
  		    &to_addr,
  		    query,
  		    LOG_ICP_QUERY,
--- 488,495 ----
  		to_addr.sin_family = AF_INET;
  		to_addr.sin_addr = ia->in_addrs[ia->cur];
  		to_addr.sin_port = htons(echo_port);
! 		query = icpPeerCreateMessage(ICP_SECHO, 0, url, reqnum, 0);
! 		icpUdpSend(thePeerIcpConnection,
  		    &to_addr,
  		    query,
  		    LOG_ICP_QUERY,
***************
*** 1061,1071 ****
      mem->start_ping = current_time;
      mem->ping_reply_callback = peerCountHandleIcpReply;
      mem->ircb_data = psstate;
!     mcastSetTtl(theOutIcpConnection, p->mcast.ttl);
      p->mcast.id = mem->id;
      reqnum = icpSetCacheKey(fake->key);
!     query = icpCreateMessage(ICP_QUERY, 0, url, reqnum, 0);
!     icpUdpSend(theOutIcpConnection,
  	&p->in_addr,
  	query,
  	LOG_ICP_QUERY,
--- 1061,1071 ----
      mem->start_ping = current_time;
      mem->ping_reply_callback = peerCountHandleIcpReply;
      mem->ircb_data = psstate;
!     mcastSetTtl(thePeerIcpConnection, p->mcast.ttl);
      p->mcast.id = mem->id;
      reqnum = icpSetCacheKey(fake->key);
!     query = icpPeerCreateMessage(ICP_QUERY, 0, url, reqnum, 0);
!     icpUdpSend(thePeerIcpConnection,
  	&p->in_addr,
  	query,
  	LOG_ICP_QUERY,
diff -cr squid-2.2.DEVEL3/src/protos.h squid-2.2.peer/src/protos.h
*** squid-2.2.DEVEL3/src/protos.h	Sat Jan 30 00:39:21 1999
--- squid-2.2.peer/src/protos.h	Sat Apr  3 21:02:18 1999
***************
*** 482,487 ****
--- 482,492 ----
      const char *url,
      int reqnum,
      int pad);
+ extern void *icpPeerCreateMessage(icp_opcode opcode,
+     int flags,
+     const char *url,
+     int reqnum,
+     int pad);
  extern int icpUdpSend(int, const struct sockaddr_in *, icp_common_t *, log_type, int);
  extern PF icpHandleUdp;
  extern PF icpUdpSendQueue;
diff -cr squid-2.2.DEVEL3/src/send-announce.c squid-2.2.peer/src/send-announce.c
*** squid-2.2.DEVEL3/src/send-announce.c	Sat Dec  5 01:54:38 1998
--- squid-2.2.peer/src/send-announce.c	Sun Apr  4 11:08:00 1999
***************
*** 43,49 ****
      void *junk;
      if (0 == Config.onoff.announce)
  	return;
!     if (theOutIcpConnection < 0)
  	return;
      cbdataAdd(junk = xmalloc(1), cbdataXfree, 0);
      ipcache_nbgethostbyname(Config.Announce.host, send_announce, junk);
--- 43,49 ----
      void *junk;
      if (0 == Config.onoff.announce)
  	return;
!     if (thePeerIcpConnection < 0)
  	return;
      cbdataAdd(junk = xmalloc(1), cbdataXfree, 0);
      ipcache_nbgethostbyname(Config.Announce.host, send_announce, junk);
***************
*** 102,112 ****
      S.sin_family = AF_INET;
      S.sin_port = htons(port);
      S.sin_addr = ia->in_addrs[0];
!     assert(theOutIcpConnection > 0);
!     x = comm_udp_sendto(theOutIcpConnection,
  	&S, sizeof(S),
  	sndbuf, strlen(sndbuf) + 1);
      if (x < 0)
! 	debug(27, 1) ("send_announce: FD %d: %s\n", theOutIcpConnection,
  	    xstrerror());
  }
--- 102,112 ----
      S.sin_family = AF_INET;
      S.sin_port = htons(port);
      S.sin_addr = ia->in_addrs[0];
!     assert(thePeerIcpConnection > 0);
!     x = comm_udp_sendto(thePeerIcpConnection,
  	&S, sizeof(S),
  	sndbuf, strlen(sndbuf) + 1);
      if (x < 0)
! 	debug(27, 1) ("send_announce: FD %d: %s\n", thePeerIcpConnection,
  	    xstrerror());
  }
diff -cr squid-2.2.DEVEL3/src/structs.h squid-2.2.peer/src/structs.h
*** squid-2.2.DEVEL3/src/structs.h	Sun Feb 14 09:35:02 1999
--- squid-2.2.peer/src/structs.h	Sat Apr  3 18:48:38 1999
***************
*** 314,319 ****
--- 314,320 ----
  	struct in_addr tcp_outgoing;
  	struct in_addr udp_incoming;
  	struct in_addr udp_outgoing;
+         struct in_addr udp_out_peer;
  #if SQUID_SNMP
  	struct in_addr snmp_incoming;
  	struct in_addr snmp_outgoing;
diff -cr squid-2.2.DEVEL3/src/tools.c squid-2.2.peer/src/tools.c
*** squid-2.2.DEVEL3/src/tools.c	Mon Jan 11 22:55:44 1999
--- squid-2.2.peer/src/tools.c	Sun Apr  4 10:57:17 1999
***************
*** 68,74 ****
--- 68,78 ----
      if (theInIcpConnection >= 0)
  	close(theInIcpConnection);
      if (theOutIcpConnection >= 0 && theOutIcpConnection != theInIcpConnection)
+     {
  	close(theOutIcpConnection);
+         if (thePeerIcpConnection != theOutIcpConnection)
+ 	  close(thePeerIcpConnection);
+     }
  }
  
  static char *

Reply via email to