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