- make the regresison test mode code build in by default. This should
[kai/samba.git] / source3 / lib / util_sock.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 #ifdef WITH_SSL
25 #include <ssl.h>
26 #undef Realloc  /* SSLeay defines this and samba has a function of this name */
27 extern SSL  *ssl;
28 extern int  sslFd;
29 #endif  /* WITH_SSL */
30
31 extern int DEBUGLEVEL;
32
33 /* the last IP received from */
34 struct in_addr lastip;
35
36 /* the last port received from */
37 int lastport=0;
38
39 int smb_read_error = 0;
40
41 /****************************************************************************
42  Determine if a file descriptor is in fact a socket.
43 ****************************************************************************/
44
45 BOOL is_a_socket(int fd)
46 {
47   int v,l;
48   l = sizeof(int);
49   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
50 }
51
52 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
53
54 typedef struct smb_socket_option
55 {
56   char *name;
57   int level;
58   int option;
59   int value;
60   int opttype;
61 } smb_socket_option;
62
63 smb_socket_option socket_options[] = {
64   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
65   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
66   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
67 #ifdef TCP_NODELAY
68   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
69 #endif
70 #ifdef IPTOS_LOWDELAY
71   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
72 #endif
73 #ifdef IPTOS_THROUGHPUT
74   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
75 #endif
76 #ifdef SO_REUSEPORT
77   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
78 #endif
79 #ifdef SO_SNDBUF
80   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
81 #endif
82 #ifdef SO_RCVBUF
83   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
84 #endif
85 #ifdef SO_SNDLOWAT
86   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
87 #endif
88 #ifdef SO_RCVLOWAT
89   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
90 #endif
91 #ifdef SO_SNDTIMEO
92   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
93 #endif
94 #ifdef SO_RCVTIMEO
95   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
96 #endif
97   {NULL,0,0,0,0}};
98
99 /****************************************************************************
100  Print socket options.
101 ****************************************************************************/
102 static void print_socket_options(int s)
103 {
104         int value, vlen = 4;
105         smb_socket_option *p = &socket_options[0];
106
107         for (; p->name != NULL; p++) {
108                 if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
109                         DEBUG(5,("Could not test socket option %s.\n", p->name));
110                 } else {
111                         DEBUG(5,("socket option %s = %d\n",p->name,value));
112                 }
113         }
114  }
115
116 /****************************************************************************
117  Set user socket options.
118 ****************************************************************************/
119
120 void set_socket_options(int fd, char *options)
121 {
122         fstring tok;
123
124         while (next_token(&options,tok," \t,", sizeof(tok))) {
125                 int ret=0,i;
126                 int value = 1;
127                 char *p;
128                 BOOL got_value = False;
129
130                 if ((p = strchr(tok,'='))) {
131                         *p = 0;
132                         value = atoi(p+1);
133                         got_value = True;
134                 }
135
136                 for (i=0;socket_options[i].name;i++)
137                         if (strequal(socket_options[i].name,tok))
138                                 break;
139
140                 if (!socket_options[i].name) {
141                         DEBUG(0,("Unknown socket option %s\n",tok));
142                         continue;
143                 }
144
145                 switch (socket_options[i].opttype) {
146                 case OPT_BOOL:
147                 case OPT_INT:
148                         ret = setsockopt(fd,socket_options[i].level,
149                                                 socket_options[i].option,(char *)&value,sizeof(int));
150                         break;
151
152                 case OPT_ON:
153                         if (got_value)
154                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
155
156                         {
157                                 int on = socket_options[i].value;
158                                 ret = setsockopt(fd,socket_options[i].level,
159                                                         socket_options[i].option,(char *)&on,sizeof(int));
160                         }
161                         break;    
162                 }
163       
164                 if (ret != 0)
165                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
166         }
167
168         print_socket_options(fd);
169 }
170
171 /****************************************************************************
172  Read from a socket.
173 ****************************************************************************/
174
175 ssize_t read_udp_socket(int fd,char *buf,size_t len)
176 {
177   ssize_t ret;
178   struct sockaddr_in sock;
179   int socklen;
180   
181   socklen = sizeof(sock);
182   memset((char *)&sock,'\0',socklen);
183   memset((char *)&lastip,'\0',sizeof(lastip));
184   ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
185   if (ret <= 0) {
186     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
187     return(0);
188   }
189
190   lastip = sock.sin_addr;
191   lastport = ntohs(sock.sin_port);
192
193   DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
194              inet_ntoa(lastip), lastport, ret));
195
196   return(ret);
197 }
198
199 /****************************************************************************
200  Read data from a socket with a timout in msec.
201  mincount = if timeout, minimum to read before returning
202  maxcount = number to be read.
203  time_out = timeout in milliseconds
204 ****************************************************************************/
205
206 static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
207 {
208   fd_set fds;
209   int selrtn;
210   ssize_t readret;
211   size_t nread = 0;
212   struct timeval timeout;
213
214   /* just checking .... */
215   if (maxcnt <= 0)
216     return(0);
217
218   smb_read_error = 0;
219
220   /* Blocking read */
221   if (time_out <= 0) {
222     if (mincnt == 0) mincnt = maxcnt;
223
224     while (nread < mincnt) {
225 #ifdef WITH_SSL
226       if(fd == sslFd){
227         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
228       }else{
229         readret = read(fd, buf + nread, maxcnt - nread);
230       }
231 #else /* WITH_SSL */
232       readret = read(fd, buf + nread, maxcnt - nread);
233 #endif /* WITH_SSL */
234
235       if (readret == 0) {
236         DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
237         smb_read_error = READ_EOF;
238         return -1;
239       }
240
241       if (readret == -1) {
242         DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
243         smb_read_error = READ_ERROR;
244         return -1;
245       }
246       nread += readret;
247     }
248     return((ssize_t)nread);
249   }
250   
251   /* Most difficult - timeout read */
252   /* If this is ever called on a disk file and 
253      mincnt is greater then the filesize then
254      system performance will suffer severely as 
255      select always returns true on disk files */
256
257   /* Set initial timeout */
258   timeout.tv_sec = (time_t)(time_out / 1000);
259   timeout.tv_usec = (long)(1000 * (time_out % 1000));
260
261   for (nread=0; nread < mincnt; ) {      
262     FD_ZERO(&fds);
263     FD_SET(fd,&fds);
264       
265     selrtn = sys_select_intr(fd+1,&fds,&timeout);
266
267     /* Check if error */
268     if(selrtn == -1) {
269       /* something is wrong. Maybe the socket is dead? */
270       DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
271       smb_read_error = READ_ERROR;
272       return -1;
273     }
274
275     /* Did we timeout ? */
276     if (selrtn == 0) {
277       DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
278       smb_read_error = READ_TIMEOUT;
279       return -1;
280     }
281       
282 #ifdef WITH_SSL
283     if(fd == sslFd){
284       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
285     }else{
286       readret = read(fd, buf + nread, maxcnt - nread);
287     }
288 #else /* WITH_SSL */
289     readret = read(fd, buf+nread, maxcnt-nread);
290 #endif /* WITH_SSL */
291
292     if (readret == 0) {
293       /* we got EOF on the file descriptor */
294       DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
295       smb_read_error = READ_EOF;
296       return -1;
297     }
298
299     if (readret == -1) {
300       /* the descriptor is probably dead */
301       DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
302       smb_read_error = READ_ERROR;
303       return -1;
304     }
305       
306     nread += readret;
307   }
308
309   /* Return the number we got */
310   return((ssize_t)nread);
311 }
312
313 /****************************************************************************
314  Read data from a fd with a timout in msec.
315  mincount = if timeout, minimum to read before returning
316  maxcount = number to be read.
317  time_out = timeout in milliseconds
318 ****************************************************************************/
319
320 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
321 {
322   fd_set fds;
323   int selrtn;
324   ssize_t readret;
325   size_t nread = 0;
326   struct timeval timeout;
327
328   /* just checking .... */
329   if (maxcnt <= 0)
330     return(0);
331
332   /* Blocking read */
333   if (time_out <= 0) {
334     if (mincnt == 0) mincnt = maxcnt;
335
336     while (nread < mincnt) {
337 #ifdef WITH_SSL
338       if(fd == sslFd){
339         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
340       }else{
341         readret = read(fd, buf + nread, maxcnt - nread);
342       }
343 #else /* WITH_SSL */
344       readret = read(fd, buf + nread, maxcnt - nread);
345 #endif /* WITH_SSL */
346
347       if (readret <= 0)
348         return readret;
349
350       nread += readret;
351     }
352     return((ssize_t)nread);
353   }
354   
355   /* Most difficult - timeout read */
356   /* If this is ever called on a disk file and 
357      mincnt is greater then the filesize then
358      system performance will suffer severely as 
359      select always returns true on disk files */
360
361   /* Set initial timeout */
362   timeout.tv_sec = (time_t)(time_out / 1000);
363   timeout.tv_usec = (long)(1000 * (time_out % 1000));
364
365   for (nread=0; nread < mincnt; ) {      
366     FD_ZERO(&fds);
367     FD_SET(fd,&fds);
368       
369     selrtn = sys_select_intr(fd+1,&fds,&timeout);
370
371     if(selrtn <= 0)
372       return selrtn;
373       
374 #ifdef WITH_SSL
375     if(fd == sslFd){
376       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
377     }else{
378       readret = read(fd, buf + nread, maxcnt - nread);
379     }
380 #else /* WITH_SSL */
381     readret = read(fd, buf+nread, maxcnt-nread);
382 #endif /* WITH_SSL */
383
384     if (readret <= 0)
385       return readret;
386
387     nread += readret;
388   }
389
390   /* Return the number we got */
391   return((ssize_t)nread);
392 }
393
394 /****************************************************************************
395 send a keepalive packet (rfc1002)
396 ****************************************************************************/
397
398 BOOL send_keepalive(int client)
399 {
400   unsigned char buf[4];
401
402   buf[0] = 0x85;
403   buf[1] = buf[2] = buf[3] = 0;
404
405   return(write_socket_data(client,(char *)buf,4) == 4);
406 }
407
408 /****************************************************************************
409   read data from the client, reading exactly N bytes. 
410 ****************************************************************************/
411
412 ssize_t read_data(int fd,char *buffer,size_t N)
413 {
414   ssize_t  ret;
415   size_t total=0;  
416  
417   smb_read_error = 0;
418
419   while (total < N)
420   {
421 #ifdef WITH_SSL
422     if(fd == sslFd){
423       ret = SSL_read(ssl, buffer + total, N - total);
424     }else{
425       ret = read(fd,buffer + total,N - total);
426     }
427 #else /* WITH_SSL */
428     ret = read(fd,buffer + total,N - total);
429 #endif /* WITH_SSL */
430
431     if (ret == 0)
432     {
433       DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
434       smb_read_error = READ_EOF;
435       return 0;
436     }
437     if (ret == -1)
438     {
439       DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
440       smb_read_error = READ_ERROR;
441       return -1;
442     }
443     total += ret;
444   }
445   return (ssize_t)total;
446 }
447
448 /****************************************************************************
449  Read data from a socket, reading exactly N bytes. 
450 ****************************************************************************/
451
452 static ssize_t read_socket_data(int fd,char *buffer,size_t N)
453 {
454   ssize_t  ret;
455   size_t total=0;  
456  
457   smb_read_error = 0;
458
459   while (total < N)
460   {
461 #ifdef WITH_SSL
462     if(fd == sslFd){
463       ret = SSL_read(ssl, buffer + total, N - total);
464     }else{
465       ret = read(fd,buffer + total,N - total);
466     }
467 #else /* WITH_SSL */
468     ret = read(fd,buffer + total,N - total);
469 #endif /* WITH_SSL */
470
471     if (ret == 0)
472     {
473       DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
474       smb_read_error = READ_EOF;
475       return 0;
476     }
477     if (ret == -1)
478     {
479       DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
480       smb_read_error = READ_ERROR;
481       return -1;
482     }
483     total += ret;
484   }
485   return (ssize_t)total;
486 }
487
488 /****************************************************************************
489  Write data to a fd.
490 ****************************************************************************/
491
492 ssize_t write_data(int fd,char *buffer,size_t N)
493 {
494   size_t total=0;
495   ssize_t ret;
496
497   while (total < N)
498   {
499 #ifdef WITH_SSL
500     if(fd == sslFd){
501       ret = SSL_write(ssl,buffer + total,N - total);
502     }else{
503       ret = write(fd,buffer + total,N - total);
504     }
505 #else /* WITH_SSL */
506     ret = write(fd,buffer + total,N - total);
507 #endif /* WITH_SSL */
508
509     if (ret == -1) {
510       DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
511       return -1;
512     }
513     if (ret == 0) return total;
514
515     total += ret;
516   }
517   return (ssize_t)total;
518 }
519
520 /****************************************************************************
521  Write data to a socket - use send rather than write.
522 ****************************************************************************/
523
524 ssize_t write_socket_data(int fd,char *buffer,size_t N)
525 {
526   size_t total=0;
527   ssize_t ret;
528
529   while (total < N)
530   {
531 #ifdef WITH_SSL
532     if(fd == sslFd){
533       ret = SSL_write(ssl,buffer + total,N - total);
534     }else{
535       ret = send(fd,buffer + total,N - total, 0);
536     }
537 #else /* WITH_SSL */
538     ret = send(fd,buffer + total,N - total,0);
539 #endif /* WITH_SSL */
540
541     if (ret == -1) {
542       DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
543       return -1;
544     }
545     if (ret == 0) return total;
546
547     total += ret;
548   }
549   return (ssize_t)total;
550 }
551
552 /****************************************************************************
553 write to a socket
554 ****************************************************************************/
555
556 ssize_t write_socket(int fd,char *buf,size_t len)
557 {
558   ssize_t ret=0;
559
560   DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
561   ret = write_socket_data(fd,buf,len);
562       
563   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
564   if(ret <= 0)
565     DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
566        (int)len, fd, strerror(errno) ));
567
568   return(ret);
569 }
570
571 /****************************************************************************
572 read 4 bytes of a smb packet and return the smb length of the packet
573 store the result in the buffer
574 This version of the function will return a length of zero on receiving
575 a keepalive packet.
576 timeout is in milliseconds.
577 ****************************************************************************/
578
579 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
580 {
581   ssize_t len=0;
582   int msg_type;
583   BOOL ok = False;
584
585   while (!ok)
586   {
587     if (timeout > 0)
588       ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
589     else 
590       ok = (read_socket_data(fd,inbuf,4) == 4);
591
592     if (!ok)
593       return(-1);
594
595     len = smb_len(inbuf);
596     msg_type = CVAL(inbuf,0);
597
598     if (msg_type == 0x85) 
599       DEBUG(5,("Got keepalive packet\n"));
600   }
601
602   DEBUG(10,("got smb length of %d\n",len));
603
604   return(len);
605 }
606
607 /****************************************************************************
608 read 4 bytes of a smb packet and return the smb length of the packet
609 store the result in the buffer. This version of the function will
610 never return a session keepalive (length of zero).
611 timeout is in milliseconds.
612 ****************************************************************************/
613
614 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
615 {
616   ssize_t len;
617
618   for(;;)
619   {
620     len = read_smb_length_return_keepalive(fd, inbuf, timeout);
621
622     if(len < 0)
623       return len;
624
625     /* Ignore session keepalives. */
626     if(CVAL(inbuf,0) != 0x85)
627       break;
628   }
629
630   DEBUG(10,("read_smb_length: got smb length of %d\n",len));
631
632   return len;
633 }
634
635 /****************************************************************************
636   read an smb from a fd. Note that the buffer *MUST* be of size
637   BUFFER_SIZE+SAFETY_MARGIN.
638   The timeout is in milliseconds. 
639   This function will return on a
640   receipt of a session keepalive packet.
641 ****************************************************************************/
642
643 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
644 {
645         ssize_t len,ret;
646
647         smb_read_error = 0;
648
649         memset(buffer,'\0',smb_size + 100);
650
651         len = read_smb_length_return_keepalive(fd,buffer,timeout);
652         if (len < 0) {
653                 DEBUG(10,("receive_smb: length < 0!\n"));
654                 return(False);
655         }
656
657         /*
658          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
659      * of header. Don't print the error if this fits.... JRA.
660          */
661
662         if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
663                 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
664                 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
665                         smb_read_error = READ_ERROR;
666                         return False;
667                 }
668         }
669
670         if(len > 0) {
671                 ret = read_socket_data(fd,buffer+4,len);
672                 if (ret != len) {
673                         smb_read_error = READ_ERROR;
674                         return False;
675                 }
676         }
677
678         return(True);
679 }
680
681 /****************************************************************************
682   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
683   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
684   The timeout is in milliseconds
685
686   This is exactly the same as receive_smb except that it never returns
687   a session keepalive packet (just as receive_smb used to do).
688   receive_smb was changed to return keepalives as the oplock processing means this call
689   should never go into a blocking read.
690 ****************************************************************************/
691
692 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
693 {
694   BOOL ret;
695
696   for(;;)
697   {
698     ret = receive_smb(fd, buffer, timeout);
699
700     if (!ret)
701     {
702       DEBUG(10,("client_receive_smb failed\n"));
703       show_msg(buffer);
704       return ret;
705     }
706
707     /* Ignore session keepalive packets. */
708     if(CVAL(buffer,0) != 0x85)
709       break;
710   }
711   show_msg(buffer);
712   return ret;
713 }
714
715 /****************************************************************************
716   send an smb to a fd 
717 ****************************************************************************/
718
719 BOOL send_smb(int fd,char *buffer)
720 {
721         size_t len;
722         size_t nwritten=0;
723         ssize_t ret;
724         len = smb_len(buffer) + 4;
725
726         while (nwritten < len) {
727                 ret = write_socket(fd,buffer+nwritten,len - nwritten);
728                 if (ret <= 0) {
729                         DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
730                                 (int)len,(int)ret, strerror(errno) ));
731                         return False;
732                 }
733                 nwritten += ret;
734         }
735
736         return True;
737 }
738
739 /****************************************************************************
740 send a single packet to a port on another machine
741 ****************************************************************************/
742
743 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
744 {
745   BOOL ret;
746   int out_fd;
747   struct sockaddr_in sock_out;
748
749   /* create a socket to write to */
750   out_fd = socket(AF_INET, type, 0);
751   if (out_fd == -1) 
752     {
753       DEBUG(0,("socket failed"));
754       return False;
755     }
756
757   /* set the address and port */
758   memset((char *)&sock_out,'\0',sizeof(sock_out));
759   putip((char *)&sock_out.sin_addr,(char *)&ip);
760   sock_out.sin_port = htons( port );
761   sock_out.sin_family = AF_INET;
762   
763   if (DEBUGLEVEL > 0)
764     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
765              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
766         
767   /* send it */
768   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
769
770   if (!ret)
771     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
772              inet_ntoa(ip),port,strerror(errno)));
773
774   close(out_fd);
775   return(ret);
776 }
777
778 /****************************************************************************
779 open a socket of the specified type, port and address for incoming data
780 ****************************************************************************/
781
782 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
783 {
784   struct hostent *hp;
785   struct sockaddr_in sock;
786   pstring host_name;
787   int res;
788
789   /* get my host name */
790   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
791     { DEBUG(0,("gethostname failed\n")); return -1; } 
792
793   /* get host info */
794   if ((hp = sys_gethostbyname(host_name)) == 0) 
795     {
796       DEBUG(0,( "sys_gethostbyname: Unknown host %s\n",host_name));
797       return -1;
798     }
799   
800   memset((char *)&sock,'\0',sizeof(sock));
801   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
802
803 #ifdef HAVE_SOCK_SIN_LEN
804   sock.sin_len = sizeof(sock);
805 #endif
806   sock.sin_port = htons( port );
807   sock.sin_family = hp->h_addrtype;
808   sock.sin_addr.s_addr = socket_addr;
809   res = socket(hp->h_addrtype, type, 0);
810   if (res == -1) 
811     { DEBUG(0,("socket failed\n")); return -1; }
812
813   {
814     int val=1;
815         if(rebind)
816                 val=1;
817         else
818                 val=0;
819     if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1)
820                 DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n",
821                         val, port, strerror(errno) ));
822 #ifdef SO_REUSEPORT
823     if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1)
824                 DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n",
825                         val, port, strerror(errno) ));
826 #endif /* SO_REUSEPORT */
827   }
828
829   /* now we've got a socket - we need to bind it */
830   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
831     { 
832       if (port) {
833         if (port == SMB_PORT || port == NMB_PORT)
834           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
835                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
836         close(res); 
837
838         if (dlevel > 0 && port < 1000)
839           port = 7999;
840
841         if (port >= 1000 && port < 9000)
842           return(open_socket_in(type,port+1,dlevel,socket_addr,rebind));
843       }
844
845       return(-1); 
846     }
847   DEBUG(3,("bind succeeded on port %d\n",port));
848
849   return res;
850 }
851
852 /****************************************************************************
853   create an outgoing socket. timeout is in milliseconds.
854   **************************************************************************/
855
856 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
857 {
858   struct sockaddr_in sock_out;
859   int res,ret;
860   int connect_loop = 250; /* 250 milliseconds */
861   int loops = (timeout) / connect_loop;
862
863   /* create a socket to write to */
864   res = socket(PF_INET, type, 0);
865   if (res == -1) 
866     { DEBUG(0,("socket error\n")); return -1; }
867
868   if (type != SOCK_STREAM) return(res);
869   
870   memset((char *)&sock_out,'\0',sizeof(sock_out));
871   putip((char *)&sock_out.sin_addr,(char *)addr);
872   
873   sock_out.sin_port = htons( port );
874   sock_out.sin_family = PF_INET;
875
876   /* set it non-blocking */
877   set_blocking(res,False);
878
879   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
880   
881   /* and connect it to the destination */
882 connect_again:
883   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
884
885   /* Some systems return EAGAIN when they mean EINPROGRESS */
886   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
887         errno == EAGAIN) && loops--) {
888     msleep(connect_loop);
889     goto connect_again;
890   }
891
892   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
893          errno == EAGAIN)) {
894       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
895       close(res);
896       return -1;
897   }
898
899 #ifdef EISCONN
900   if (ret < 0 && errno == EISCONN) {
901     errno = 0;
902     ret = 0;
903   }
904 #endif
905
906   if (ret < 0) {
907     DEBUG(1,("error connecting to %s:%d (%s)\n",
908              inet_ntoa(*addr),port,strerror(errno)));
909     close(res);
910     return -1;
911   }
912
913   /* set it blocking again */
914   set_blocking(res,True);
915
916   return res;
917 }
918
919 /* the following 3 client_*() functions are nasty ways of allowing
920    some generic functions to get info that really should be hidden in
921    particular modules */
922 static int client_fd = -1;
923
924 void client_setfd(int fd)
925 {
926         client_fd = fd;
927 }
928
929 char *client_name(void)
930 {
931         return get_socket_name(client_fd);
932 }
933
934 char *client_addr(void)
935 {
936         return get_socket_addr(client_fd);
937 }
938
939 /*******************************************************************
940  matchname - determine if host name matches IP address. Used to
941  confirm a hostname lookup to prevent spoof attacks
942  ******************************************************************/
943 static BOOL matchname(char *remotehost,struct in_addr  addr)
944 {
945         struct hostent *hp;
946         int     i;
947         
948         if ((hp = sys_gethostbyname(remotehost)) == 0) {
949                 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
950                 return False;
951         } 
952
953         /*
954          * Make sure that gethostbyname() returns the "correct" host name.
955          * Unfortunately, gethostbyname("localhost") sometimes yields
956          * "localhost.domain". Since the latter host name comes from the
957          * local DNS, we just have to trust it (all bets are off if the local
958          * DNS is perverted). We always check the address list, though.
959          */
960         
961         if (strcasecmp(remotehost, hp->h_name)
962             && strcasecmp(remotehost, "localhost")) {
963                 DEBUG(0,("host name/name mismatch: %s != %s\n",
964                          remotehost, hp->h_name));
965                 return False;
966         }
967         
968         /* Look up the host address in the address list we just got. */
969         for (i = 0; hp->h_addr_list[i]; i++) {
970                 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
971                         return True;
972         }
973         
974         /*
975          * The host name does not map to the original host address. Perhaps
976          * someone has compromised a name server. More likely someone botched
977          * it, but that could be dangerous, too.
978          */
979         
980         DEBUG(0,("host name/address mismatch: %s != %s\n",
981                  inet_ntoa(addr), hp->h_name));
982         return False;
983 }
984
985  
986 /*******************************************************************
987  return the DNS name of the remote end of a socket
988  ******************************************************************/
989 char *get_socket_name(int fd)
990 {
991         static pstring name_buf;
992         static fstring addr_buf;
993         struct hostent *hp;
994         struct in_addr addr;
995         char *p;
996         
997         p = get_socket_addr(fd);
998
999         /* it might be the same as the last one - save some DNS work */
1000         if (strcmp(p, addr_buf) == 0) return name_buf;
1001
1002         pstrcpy(name_buf,"UNKNOWN");
1003         if (fd == -1) return name_buf;
1004
1005         fstrcpy(addr_buf, p);
1006
1007         addr = *interpret_addr2(p);
1008         
1009         /* Look up the remote host name. */
1010         if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
1011                 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
1012                 pstrcpy(name_buf, p);
1013         } else {
1014                 pstrcpy(name_buf,(char *)hp->h_name);
1015                 if (!matchname(name_buf, addr)) {
1016                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
1017                         pstrcpy(name_buf,"UNKNOWN");
1018                 }
1019         }
1020         return name_buf;
1021 }
1022
1023 /*******************************************************************
1024  return the IP addr of the remote end of a socket as a string 
1025  ******************************************************************/
1026 char *get_socket_addr(int fd)
1027 {
1028         struct sockaddr sa;
1029         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
1030         int     length = sizeof(sa);
1031         static fstring addr_buf;
1032
1033         fstrcpy(addr_buf,"0.0.0.0");
1034
1035         if (fd == -1) {
1036                 return addr_buf;
1037         }
1038         
1039         if (getpeername(fd, &sa, &length) < 0) {
1040                 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
1041                 return addr_buf;
1042         }
1043         
1044         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
1045         
1046         return addr_buf;
1047 }
1048
1049 /*******************************************************************
1050  opens and connects to a unix pipe socket
1051  ******************************************************************/
1052 int open_pipe_sock(char *path)
1053 {
1054         int sock;
1055         struct sockaddr_un sa;
1056
1057         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1058
1059         if (sock < 0)
1060         {
1061                 DEBUG(0, ("unix socket open failed\n"));
1062                 return sock;
1063         }
1064
1065         ZERO_STRUCT(sa);
1066         sa.sun_family = AF_UNIX;
1067         safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
1068
1069         DEBUG(10, ("socket open succeeded.  file name: %s\n", sa.sun_path));
1070
1071         if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
1072         {
1073                 DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
1074                 close(sock);
1075                 return -1;
1076         }
1077
1078         return sock;
1079 }
1080
1081 int create_pipe_socket(char *dir, int dir_perms,
1082                                 char *path, int path_perms)
1083 {
1084         int s;
1085         struct sockaddr_un sa;
1086
1087         DEBUG(0,("create_pipe_socket: %s %d %s %d\n",
1088                    dir, dir_perms, path, path_perms));
1089
1090         DEBUG(0,("*** RACE CONDITION.  PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n"));
1091
1092         mkdir(dir, dir_perms);
1093
1094         if (chmod(dir, dir_perms) < 0)
1095         {
1096                 DEBUG(0, ("chmod on %s failed\n", dir));
1097                 return -1;
1098         }
1099
1100         if (!remove(path))
1101         {
1102                 DEBUG(0, ("remove on %s failed\n", path));
1103         }
1104                 
1105         /* start listening on unix socket */
1106         s = socket(AF_UNIX, SOCK_STREAM, 0);
1107
1108         if (s < 0)
1109         {
1110                 DEBUG(0, ("socket open failed\n"));
1111                 return -1;
1112         }
1113
1114         ZERO_STRUCT(sa);
1115         sa.sun_family = AF_UNIX;
1116         safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
1117
1118         if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
1119         {
1120                 DEBUG(0, ("socket bind to %s failed\n", sa.sun_path));
1121                 close(s);
1122                 remove(path);
1123                 return -1;
1124         }
1125
1126         if (s == -1)
1127         {
1128                 DEBUG(0,("bind failed\n"));
1129                 remove(path);
1130                 return -1;
1131         }
1132
1133         if (path_perms != 0)
1134         {
1135                 chmod(path, path_perms);
1136         }
1137
1138         if (listen(s, 5) == -1)
1139         {
1140                 DEBUG(0,("listen failed\n"));
1141                 return -1;
1142         }
1143
1144         DEBUG(5,("unix socket opened: %s\n", path));
1145
1146         return s;
1147 }
1148
1149 /*******************************************************************
1150 this is like socketpair but uses tcp. It is used by the Samba
1151 regression test code
1152 The function guarantees that nobody else can attach to the socket,
1153 or if they do that this function fails and the socket gets closed
1154 returns 0 on success, -1 on failure
1155 the resulting file descriptors are symmetrical
1156  ******************************************************************/
1157 static int socketpair_tcp(int fd[2])
1158 {
1159         int listener;
1160         struct sockaddr sock;
1161         socklen_t socklen = sizeof(sock);
1162         int connect_done = 0;
1163         
1164         fd[0] = fd[1] = listener = -1;
1165
1166         memset(&sock, 0, sizeof(sock));
1167         
1168         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1169
1170         if (listen(listener, 1) != 0) goto failed;
1171
1172         if (getsockname(listener, &sock, &socklen) != 0) goto failed;
1173
1174         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
1175
1176         set_blocking(fd[1], 0);
1177
1178         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
1179                 if (errno != EINPROGRESS) goto failed;
1180         } else {
1181                 connect_done = 1;
1182         }
1183
1184         if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed;
1185
1186         close(listener);
1187         if (connect_done == 0) {
1188                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0) goto failed;
1189         }
1190
1191         set_blocking(fd[1], 1);
1192
1193         /* all OK! */
1194         return 0;
1195
1196  failed:
1197         if (fd[0] != -1) close(fd[0]);
1198         if (fd[1] != -1) close(fd[1]);
1199         if (listener != -1) close(listener);
1200         return -1;
1201 }
1202
1203
1204 /*******************************************************************
1205 run a program on a local tcp socket, this is used to launch smbd
1206 when regression testing
1207 the return value is a socket which is attached to a subprocess
1208 running "prog". stdin and stdout are attached. stderr is left
1209 attached to the original stderr
1210  ******************************************************************/
1211 int sock_exec(const char *prog)
1212 {
1213         int fd[2];
1214         if (socketpair_tcp(fd) != 0) return -1;
1215         if (fork() == 0) {
1216                 close(fd[0]);
1217                 close(0);
1218                 close(1);
1219                 dup(fd[1]);
1220                 dup(fd[1]);
1221                 exit(system(prog));
1222         }
1223         close(fd[1]);
1224         return fd[0];
1225 }
1226