Article delegate-en/4842 of [1-5169] on the server localhost:119
  upper oldest olders older1 this newer1 newers latest
search
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
[Reference:<_A4840@delegate-en.ML_>]
Newsgroups: mail-lists.delegate-en

[DeleGate-En] Re: RES_NS not following SRCIF instruction in Delegate 9.9.7
12 Jun 2010 04:33:20 GMT feedback@delegate.org (Yutaka Sato)
The DeleGate Project


Chris,

In message <_A4840@delegate-en.ML_> on 06/11/10(17:21:41)
you Chris Murton <p4ejabdyi-qjiq2jylzdzr.ml@ml.delegate.org> wrote:
 |As ever, a lightning fast response and solution. I've patched the larger update into delegate9.9.8-pre5 and it's working perfectly, thank you for your time and dedication!

It took several minutes to make and test the smaller patch.
It took other ten minutes for larger one without conditional matching as
"SRCIF=Addr:0:dns".

But when I tried to enable the full functionality of SRCIF with condition
as "SRCIF=Host:Port1-Port2:dns:Dst:Src", I encountered loop and crash.
The loop occurred because the SRCIF calls the resolver while the resolver
calls SRCIF.  It took about 3 hours to find and validate a solution that
will not cause side-effect for existing behavior and usage.  (I should
remember that it can cause another problem (resulution failure at the first
DNS query) when SRCIF for DNS is used in multi-thread execution mode of
DeleGate in future...)

Today, I reviewed the modification to see if or not it makes side-effect
to the existing behavior, and found it does not work with a simple
SRCIF specification as follows:

  SRCIF="host"

which is equivalent to the following:

  SRCIF="host:-:*:*:*"

The cause of the failure is simply because an integer variable for the
default port number (refered by "-" as the port number specification)
to be used for binding is not initialized.

Since it is not likely to be expected that SRCIF by genric configuration
as above is applied to the port for DNS resolver, I'll eliminate the
appliction of SRCIF for DNS so that it is enabled only when it is specified
not with the wild card ("*") but with the specific protocol name "dns"
explicitly as SRCIF="host:port:dns".
(I'm writing the above for my own memory :-)

The modification will be released as the enclosed patch in 9.9.8-pre6.

Cheers,
Yutaka
--
  9 9   Yutaka Sato <y.sato@delegate.org> http://delegate.org/y.sato/
 ( ~ )  National Institute of Advanced Industrial Science and Technology
_<   >_ 1-1-4 Umezono, Tsukuba, Ibaraki, 305-8568 Japan
Do the more with the less -- B. Fuller

diff -cr dist/src/delegate9.9.8-pre5/src/master.c ./src/master.c
*** dist/src/delegate9.9.8-pre5/src/master.c	Thu Mar 18 16:29:12 2010
--- ./src/master.c	Sat Jun 12 12:34:22 2010
***************
*** 489,496 ****
--- 489,504 ----
  static int protoMatch3(Server *protoV,PCStr(proto))
  {	int px;
  	const char *aproto;
+ 	int exactmatch = 0;
  
+ 	if( *proto == '-' ){
+ 		exactmatch = 1;
+ 		proto++;
+ 	}
  	for( px = 0; aproto = protoV[px].p_name; px++ ){
+ 		if( exactmatch && *aproto == '*' ){
+ 			continue;
+ 		}
  		if( *proto=='*' || *aproto=='*' || strcasecmp(proto,aproto)==0 )
  			return 1;
  	}
diff -cr dist/src/delegate9.9.8-pre5/resolvy/resolv.c ./resolvy/resolv.c
*** dist/src/delegate9.9.8-pre5/resolvy/resolv.c	Sun Jan 31 20:12:31 2010
--- ./resolvy/resolv.c	Sat Jun 12 12:58:11 2010
***************
*** 546,551 ****
--- 546,611 ----
  
  static VSAddr *Me;
  
+ DGC*MainConn();
+ const char *gethostaddrX(PCStr(host));
+ int SRCIFfor(DGC*Conn,PCStr(proto),PCStr(rhost),int rport,PVStr(lhost),int *lport);
+ 
+ int bindVSA_SRCIFfor(int sock,PCStr(proto),VSAddr *dst,VSAddr *srcif){
+ 	const char *host = VSA_ntoa(dst);
+ 	int port = VSA_port(dst);
+ 	IStr(lhost,MaxHostNameLen);
+ 	int lports,lport1,lport2,port1,ntry;
+ 	IStr(laddr,64);
+ 	int len;
+ 	int rcode;
+ 
+ 	lports = 0;
+ 	if( SRCIFfor(MainConn(),proto,host,port,AVStr(lhost),&lports) ){
+ 		if( lports == 0xFFFF0000 ){
+ 			lport1 = lport2 = 0;
+ 		}else{
+ 			lport1 = 0xFFFF & (lports >> 16);
+ 			lport2 = 0xFFFF & lports;
+ 		}
+ 		strcpy(laddr,gethostaddrX(lhost));
+ 		VSA_atosa(srcif,0,laddr);
+ 		ntry = 32;
+ 		for( port1 = lport1; port1 <= lport2; port1++ ){
+ 			VSA_setport(srcif,port1);
+ 			len = VSA_size(srcif);
+ 			rcode = bind(sock,(SAP)srcif,len);
+ 			debug(DBG_FORCE,"## SRCIF %s:%d <= %s://%s:%d = %d\n",
+ 				laddr,port1,proto,host,port,rcode);
+ 			if( rcode == 0 ){
+ 				return 0;
+ 			}
+ 			if( ntry-- < 0 ){
+ 				break;
+ 			}
+ 		}
+ 		return -2;
+ 	}
+ 	return -1;
+ }
+ static int inInitSRCIFforDNS;
+ static int bindSRCIFforDNS(int sock,VSAddr *Ns,VSAddr *srcif){
+ 	int rcode;
+ 
+ 	if( inInitSRCIFforDNS ){
+ 		/* this loop must not happen */
+ 		debug(DBG_FORCE,"FATAL #### loop in SRCIFforDNS (%d)\n",
+ 			inInitSRCIFforDNS);
+ 		return -9;
+ 	}else{
+ 		inInitSRCIFforDNS++;
+ 		/* should suppress DNS resolver during the following call */
+ 		/* "-dns" for exact matching with explicit SRCIF=H:P:"dns" */
+ 		rcode = bindVSA_SRCIFfor(sock,"-dns",Ns,srcif);
+ 		inInitSRCIFforDNS--;
+ 		return rcode;
+ 	}
+ }
+ 
  static int makeMysock()
  {	int len;
  	int rcode;
***************
*** 576,581 ****
--- 636,645 ----
  	}else
  	me = "0.0.0.0";
  	len = VSA_atosa(Me,0,me);
+ 
+ 	if( (rcode = bindSRCIFforDNS(mysock,&Ns,Me)) == 0 ){
+ 		/* bound by SRCIF=Host:Port:dns */
+ 	}else
  	rcode = bind(mysock,(SAP)Me,len);
  	if( rcode < 0 ){
  		debug(DBG_FORCE,"cannot bind() [errno=%d]\n",errno);
***************
*** 1459,1464 ****
--- 1523,1533 ----
  	int mx,nmx,mxi,rmx;
  	char *mxv[64]; /*QA(QC)*/
  
+ 	if( inInitSRCIFforDNS ){
+ 		debug(DBG_FORCE,"----DNS in init, ignored Q [%s]\n",name);
+ 		return 0;
+ 	}
+ 
  	putResTrace("DNS{%s}",name);
  	if( strncasecmp(name,"_srv.",5) == 0 ){
  		name += 5;

  admin search upper oldest olders older1 this newer1 newers latest
[Top/Up] [oldest] - [Older+chunk] - [Newer+chunk] - [newest + Check]
@_@V