diff -u stunnel-3.14.orig/common.h stunnel-3.14/common.h --- stunnel-3.14.orig/common.h Wed Feb 21 10:08:31 2001 +++ stunnel-3.14/common.h Fri May 25 15:14:33 2001 @@ -26,6 +26,7 @@ #define OPT_REMOTE 0x20 #define OPT_TRANSPARENT 0x40 #define OPT_PTY 0x80 +#define OPT_DELAYLOOKUP 0x100 /* Certificate defaults */ @@ -202,6 +203,7 @@ int random_bytes; /* how many random bytes to read */ char *pid_dir; int cert_defaults; + char *r_arg; } server_options; /* Prototypes for stunnel.c */ diff -u stunnel-3.14.orig/stunnel.c stunnel-3.14/stunnel.c --- stunnel-3.14.orig/stunnel.c Wed Feb 21 09:55:28 2001 +++ stunnel-3.14/stunnel.c Fri May 25 15:41:19 2001 @@ -113,9 +113,9 @@ #ifndef USE_WIN32 static int make_sockets(int [2]); #endif -static void name2nums(char *, u32 **, u_short *); +static int name2nums(char *, u32 **, u_short *); static u_short port2num(char *); -static void host2num(u32 **, char *); +static int host2num(u32 **, char *); /* Error/exceptions handling functions */ static void ioerror(char *); @@ -243,7 +243,7 @@ options.rand_write=1; options.random_bytes=RANDOM_BYTES; opterr=0; - while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:E:R:WB:VP:S:")) != EOF) + while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:E:R:WB:VP:S:y")) != EOF) switch (c) { case 'A': safecopy(options.cert_file,optarg); @@ -289,7 +289,8 @@ } options.option|=OPT_DAEMON; options.localnames=NULL; - name2nums(optarg, &options.localnames, &options.localport); + if (name2nums(optarg, &options.localnames, &options.localport) != 0) + exit(1); if(!options.localnames) { alloc(&options.localnames, 1); options.localnames[0]=htonl(INADDR_ANY); @@ -338,11 +339,8 @@ safestring(options.servname); } options.remotenames=NULL; - name2nums(optarg, &options.remotenames, &options.remoteport); - if (!options.remotenames) { - alloc(&options.remotenames, 1); - options.remotenames[0] = htonl(INADDR_LOOPBACK); - } + options.r_arg = malloc(strlen(optarg)*sizeof(char)); + strcpy(options.r_arg, optarg); break; case 's': options.setuid_user=optarg; @@ -381,6 +379,9 @@ case 'P': options.pid_dir=optarg; break; + case 'y': + options.option |= OPT_DELAYLOOKUP; + break; case '?': log(LOG_ERR, "Illegal option: '%c'", optopt); case 'h': @@ -395,6 +396,17 @@ print_help(); } #endif + if (!(options.option & OPT_DELAYLOOKUP)) { + if (options.option & OPT_REMOTE) { + if (name2nums(options.r_arg, &options.remotenames, &options.remoteport) != 0) + exit(1); + if (!options.remotenames) { + alloc(&options.remotenames, 1); + options.remotenames[0] = htonl(INADDR_LOOPBACK); + } + } + } + if (options.option & OPT_CLIENT) { if (!(options.option & OPT_REMOTE)) { log(LOG_ERR, "Remote service must be specified"); @@ -740,6 +752,17 @@ } } + if (options.option & (OPT_DELAYLOOKUP|OPT_REMOTE)) { + if (name2nums(options.r_arg, &options.remotenames, &options.remoteport) != 0) { + sockerror("remote lookup"); + return -1; + } + if (!options.remotenames) { + alloc(&options.remotenames, 1); + options.remotenames[0] = htonl(INADDR_LOOPBACK); + } + } + addr.sin_port=options.remoteport; /* connect each host from the list*/ @@ -867,18 +890,20 @@ } #endif -static void name2nums(char *name, u32 **names, u_short *port) +static int name2nums(char *name, u32 **names, u_short *port) { char hostname[STRLEN], *portname; + int ret = 0; safecopy(hostname, name); if((portname=strrchr(hostname, ':'))) { *portname++='\0'; - host2num(names, hostname); + ret = host2num(names, hostname); *port=port2num(portname); } else { *port=port2num(hostname); /* no ':' - use default host IP */ } + return ret; } static u_short port2num(char *portname) /* get port number */ @@ -897,7 +922,7 @@ return port; } -static void host2num(u32 **hostlist, char *hostname) +static int host2num(u32 **hostlist, char *hostname) { /* get list of host addresses */ struct hostent *h; u32 ip; @@ -908,12 +933,12 @@ if(ip!=-1) { /* dotted decimal */ alloc(hostlist, 1); (*hostlist)[0]=ip; - return; + return 0; } /* not dotted decimal - we have to call resolver */ if(!(h=gethostbyname(hostname))) { /* get list of addresses */ sockerror("gethostbyname"); - exit(1); + return -1; } i=0; tab=h->h_addr_list; @@ -922,6 +947,7 @@ alloc(hostlist, i); /* allocate memory */ while(--i>=0) (*hostlist)[i]=*(u32 *)(h->h_addr_list[i]); + return 0; } static void ioerror(char *txt) /* Input/Output error handler */ @@ -1106,6 +1132,7 @@ "\n" "\n -d [host:]port daemon mode (host defaults to INADDR_ANY)" "\n -r [host:]port connect to remote service (host defaults to INADDR_LOOPBACK)" + "\n -y delay lookup of remote service address until connect time" #ifndef USE_WIN32 "\n -l program\t execute local inetd-type program" "\n -L program\t open local pty and execute program"