Added support for SO_REUSEPORT for systems that have it.
[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 BOOL passive = False;
34
35 /* the client file descriptor */
36 int Client = -1;
37
38 /* the last IP received from */
39 struct in_addr lastip;
40
41 /* the last port received from */
42 int lastport=0;
43
44 int smb_read_error = 0;
45
46 /****************************************************************************
47  Determine if a file descriptor is in fact a socket.
48 ****************************************************************************/
49
50 BOOL is_a_socket(int fd)
51 {
52   int v,l;
53   l = sizeof(int);
54   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
55 }
56
57 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
58
59 struct
60 {
61   char *name;
62   int level;
63   int option;
64   int value;
65   int opttype;
66 } socket_options[] = {
67   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
68   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
69   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
70 #ifdef TCP_NODELAY
71   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
72 #endif
73 #ifdef IPTOS_LOWDELAY
74   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
75 #endif
76 #ifdef IPTOS_THROUGHPUT
77   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
78 #endif
79 #ifdef SO_REUSEPORT
80   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
81 #endif
82 #ifdef SO_SNDBUF
83   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
84 #endif
85 #ifdef SO_RCVBUF
86   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
87 #endif
88 #ifdef SO_SNDLOWAT
89   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
90 #endif
91 #ifdef SO_RCVLOWAT
92   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
93 #endif
94 #ifdef SO_SNDTIMEO
95   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
96 #endif
97 #ifdef SO_RCVTIMEO
98   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
99 #endif
100   {NULL,0,0,0,0}};
101
102 /****************************************************************************
103  Set user socket options.
104 ****************************************************************************/
105
106 void set_socket_options(int fd, char *options)
107 {
108         fstring tok;
109
110         while (next_token(&options,tok," \t,", sizeof(tok))) {
111                 int ret=0,i;
112                 int value = 1;
113                 char *p;
114                 BOOL got_value = False;
115
116                 if ((p = strchr(tok,'='))) {
117                         *p = 0;
118                         value = atoi(p+1);
119                         got_value = True;
120                 }
121
122                 for (i=0;socket_options[i].name;i++)
123                         if (strequal(socket_options[i].name,tok))
124                                 break;
125
126                 if (!socket_options[i].name) {
127                         DEBUG(0,("Unknown socket option %s\n",tok));
128                         continue;
129                 }
130
131                 switch (socket_options[i].opttype) {
132                 case OPT_BOOL:
133                 case OPT_INT:
134                         ret = setsockopt(fd,socket_options[i].level,
135                                                 socket_options[i].option,(char *)&value,sizeof(int));
136                         break;
137
138                 case OPT_ON:
139                         if (got_value)
140                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
141
142                         {
143                                 int on = socket_options[i].value;
144                                 ret = setsockopt(fd,socket_options[i].level,
145                                                         socket_options[i].option,(char *)&on,sizeof(int));
146                         }
147                         break;    
148                 }
149       
150                 if (ret != 0)
151                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
152         }
153 }
154
155 /****************************************************************************
156  Close the socket communication.
157 ****************************************************************************/
158
159 void close_sockets(void )
160 {
161 #ifdef WITH_SSL
162   sslutil_disconnect(Client);
163 #endif /* WITH_SSL */
164
165   close(Client);
166   Client = -1;
167 }
168
169 /****************************************************************************
170  Read from a socket.
171 ****************************************************************************/
172
173 ssize_t read_udp_socket(int fd,char *buf,size_t len)
174 {
175   ssize_t ret;
176   struct sockaddr_in sock;
177   int socklen;
178   
179   socklen = sizeof(sock);
180   memset((char *)&sock,'\0',socklen);
181   memset((char *)&lastip,'\0',sizeof(lastip));
182   ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
183   if (ret <= 0) {
184     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
185     return(0);
186   }
187
188   lastip = sock.sin_addr;
189   lastport = ntohs(sock.sin_port);
190
191   DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
192              inet_ntoa(lastip), lastport, ret));
193
194   return(ret);
195 }
196
197 /****************************************************************************
198  Read data from a socket with a timout in msec.
199  mincount = if timeout, minimum to read before returning
200  maxcount = number to be read.
201  time_out = timeout in milliseconds
202 ****************************************************************************/
203
204 static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
205 {
206   fd_set fds;
207   int selrtn;
208   ssize_t readret;
209   size_t nread = 0;
210   struct timeval timeout;
211
212   /* just checking .... */
213   if (maxcnt <= 0)
214     return(0);
215
216   smb_read_error = 0;
217
218   /* Blocking read */
219   if (time_out <= 0) {
220     if (mincnt == 0) mincnt = maxcnt;
221
222     while (nread < mincnt) {
223 #ifdef WITH_SSL
224       if(fd == sslFd){
225         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
226       }else{
227         readret = read(fd, buf + nread, maxcnt - nread);
228       }
229 #else /* WITH_SSL */
230       readret = read(fd, buf + nread, maxcnt - nread);
231 #endif /* WITH_SSL */
232
233       if (readret == 0) {
234         DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
235         smb_read_error = READ_EOF;
236         return -1;
237       }
238
239       if (readret == -1) {
240         DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
241         smb_read_error = READ_ERROR;
242         return -1;
243       }
244       nread += readret;
245     }
246     return((ssize_t)nread);
247   }
248   
249   /* Most difficult - timeout read */
250   /* If this is ever called on a disk file and 
251      mincnt is greater then the filesize then
252      system performance will suffer severely as 
253      select always returns true on disk files */
254
255   /* Set initial timeout */
256   timeout.tv_sec = (time_t)(time_out / 1000);
257   timeout.tv_usec = (long)(1000 * (time_out % 1000));
258
259   for (nread=0; nread < mincnt; ) {      
260     FD_ZERO(&fds);
261     FD_SET(fd,&fds);
262       
263     selrtn = sys_select(fd+1,&fds,&timeout);
264
265     /* Check if error */
266     if(selrtn == -1) {
267       /* something is wrong. Maybe the socket is dead? */
268       DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
269       smb_read_error = READ_ERROR;
270       return -1;
271     }
272
273     /* Did we timeout ? */
274     if (selrtn == 0) {
275       DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
276       smb_read_error = READ_TIMEOUT;
277       return -1;
278     }
279       
280 #ifdef WITH_SSL
281     if(fd == sslFd){
282       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
283     }else{
284       readret = read(fd, buf + nread, maxcnt - nread);
285     }
286 #else /* WITH_SSL */
287     readret = read(fd, buf+nread, maxcnt-nread);
288 #endif /* WITH_SSL */
289
290     if (readret == 0) {
291       /* we got EOF on the file descriptor */
292       DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
293       smb_read_error = READ_EOF;
294       return -1;
295     }
296
297     if (readret == -1) {
298       /* the descriptor is probably dead */
299       DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
300       smb_read_error = READ_ERROR;
301       return -1;
302     }
303       
304     nread += readret;
305   }
306
307   /* Return the number we got */
308   return((ssize_t)nread);
309 }
310
311 /****************************************************************************
312  Read data from a fd with a timout in msec.
313  mincount = if timeout, minimum to read before returning
314  maxcount = number to be read.
315  time_out = timeout in milliseconds
316 ****************************************************************************/
317
318 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
319 {
320   fd_set fds;
321   int selrtn;
322   ssize_t readret;
323   size_t nread = 0;
324   struct timeval timeout;
325
326   /* just checking .... */
327   if (maxcnt <= 0)
328     return(0);
329
330   /* Blocking read */
331   if (time_out <= 0) {
332     if (mincnt == 0) mincnt = maxcnt;
333
334     while (nread < mincnt) {
335 #ifdef WITH_SSL
336       if(fd == sslFd){
337         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
338       }else{
339         readret = read(fd, buf + nread, maxcnt - nread);
340       }
341 #else /* WITH_SSL */
342       readret = read(fd, buf + nread, maxcnt - nread);
343 #endif /* WITH_SSL */
344
345       if (readret <= 0)
346         return readret;
347
348       nread += readret;
349     }
350     return((ssize_t)nread);
351   }
352   
353   /* Most difficult - timeout read */
354   /* If this is ever called on a disk file and 
355      mincnt is greater then the filesize then
356      system performance will suffer severely as 
357      select always returns true on disk files */
358
359   /* Set initial timeout */
360   timeout.tv_sec = (time_t)(time_out / 1000);
361   timeout.tv_usec = (long)(1000 * (time_out % 1000));
362
363   for (nread=0; nread < mincnt; ) {      
364     FD_ZERO(&fds);
365     FD_SET(fd,&fds);
366       
367     selrtn = sys_select(fd+1,&fds,&timeout);
368
369     if(selrtn <= 0)
370       return selrtn;
371       
372 #ifdef WITH_SSL
373     if(fd == sslFd){
374       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
375     }else{
376       readret = read(fd, buf + nread, maxcnt - nread);
377     }
378 #else /* WITH_SSL */
379     readret = read(fd, buf+nread, maxcnt-nread);
380 #endif /* WITH_SSL */
381
382     if (readret <= 0)
383       return readret;
384
385     nread += readret;
386   }
387
388   /* Return the number we got */
389   return((ssize_t)nread);
390 }
391
392 /****************************************************************************
393 send a keepalive packet (rfc1002)
394 ****************************************************************************/
395
396 BOOL send_keepalive(int client)
397 {
398   unsigned char buf[4];
399
400   buf[0] = 0x85;
401   buf[1] = buf[2] = buf[3] = 0;
402
403   return(write_socket_data(client,(char *)buf,4) == 4);
404 }
405
406 /****************************************************************************
407   read data from the client, reading exactly N bytes. 
408 ****************************************************************************/
409
410 ssize_t read_data(int fd,char *buffer,size_t N)
411 {
412   ssize_t  ret;
413   size_t total=0;  
414  
415   smb_read_error = 0;
416
417   while (total < N)
418   {
419 #ifdef WITH_SSL
420     if(fd == sslFd){
421       ret = SSL_read(ssl, buffer + total, N - total);
422     }else{
423       ret = read(fd,buffer + total,N - total);
424     }
425 #else /* WITH_SSL */
426     ret = read(fd,buffer + total,N - total);
427 #endif /* WITH_SSL */
428
429     if (ret == 0)
430     {
431       DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
432       smb_read_error = READ_EOF;
433       return 0;
434     }
435     if (ret == -1)
436     {
437       DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
438       smb_read_error = READ_ERROR;
439       return -1;
440     }
441     total += ret;
442   }
443   return (ssize_t)total;
444 }
445
446 /****************************************************************************
447  Read data from a socket, reading exactly N bytes. 
448 ****************************************************************************/
449
450 static ssize_t read_socket_data(int fd,char *buffer,size_t N)
451 {
452   ssize_t  ret;
453   size_t total=0;  
454  
455   smb_read_error = 0;
456
457   while (total < N)
458   {
459 #ifdef WITH_SSL
460     if(fd == sslFd){
461       ret = SSL_read(ssl, buffer + total, N - total);
462     }else{
463       ret = read(fd,buffer + total,N - total);
464     }
465 #else /* WITH_SSL */
466     ret = read(fd,buffer + total,N - total);
467 #endif /* WITH_SSL */
468
469     if (ret == 0)
470     {
471       DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
472       smb_read_error = READ_EOF;
473       return 0;
474     }
475     if (ret == -1)
476     {
477       DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
478       smb_read_error = READ_ERROR;
479       return -1;
480     }
481     total += ret;
482   }
483   return (ssize_t)total;
484 }
485
486 /****************************************************************************
487  Write data to a fd.
488 ****************************************************************************/
489
490 ssize_t write_data(int fd,char *buffer,size_t N)
491 {
492   size_t total=0;
493   ssize_t ret;
494
495   while (total < N)
496   {
497 #ifdef WITH_SSL
498     if(fd == sslFd){
499       ret = SSL_write(ssl,buffer + total,N - total);
500     }else{
501       ret = write(fd,buffer + total,N - total);
502     }
503 #else /* WITH_SSL */
504     ret = write(fd,buffer + total,N - total);
505 #endif /* WITH_SSL */
506
507     if (ret == -1) {
508       DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
509       return -1;
510     }
511     if (ret == 0) return total;
512
513     total += ret;
514   }
515   return (ssize_t)total;
516 }
517
518 /****************************************************************************
519  Write data to a socket - use send rather than write.
520 ****************************************************************************/
521
522 ssize_t write_socket_data(int fd,char *buffer,size_t N)
523 {
524   size_t total=0;
525   ssize_t ret;
526
527   while (total < N)
528   {
529 #ifdef WITH_SSL
530     if(fd == sslFd){
531       ret = SSL_write(ssl,buffer + total,N - total);
532     }else{
533       ret = send(fd,buffer + total,N - total, 0);
534     }
535 #else /* WITH_SSL */
536     ret = send(fd,buffer + total,N - total,0);
537 #endif /* WITH_SSL */
538
539     if (ret == -1) {
540       DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
541       return -1;
542     }
543     if (ret == 0) return total;
544
545     total += ret;
546   }
547   return (ssize_t)total;
548 }
549
550 /****************************************************************************
551 write to a socket
552 ****************************************************************************/
553
554 ssize_t write_socket(int fd,char *buf,size_t len)
555 {
556   ssize_t ret=0;
557
558   if (passive)
559     return(len);
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   {
654     DEBUG(10,("receive_smb: length < 0!\n"));
655     return(False);
656   }
657
658   if (len > BUFFER_SIZE) {
659     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
660     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
661     {
662         exit(1);
663     }
664   }
665
666   if(len > 0) {
667     ret = read_socket_data(fd,buffer+4,len);
668     if (ret != len) {
669       smb_read_error = READ_ERROR;
670       return False;
671     }
672   }
673   return(True);
674 }
675
676 /****************************************************************************
677   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
678   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
679   The timeout is in milliseconds
680
681   This is exactly the same as receive_smb except that it never returns
682   a session keepalive packet (just as receive_smb used to do).
683   receive_smb was changed to return keepalives as the oplock processing means this call
684   should never go into a blocking read.
685 ****************************************************************************/
686
687 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
688 {
689   BOOL ret;
690
691   for(;;)
692   {
693     ret = receive_smb(fd, buffer, timeout);
694
695     if (!ret)
696     {
697       DEBUG(10,("client_receive_smb failed\n"));
698       show_msg(buffer);
699       return ret;
700     }
701
702     /* Ignore session keepalive packets. */
703     if(CVAL(buffer,0) != 0x85)
704       break;
705   }
706   show_msg(buffer);
707   return ret;
708 }
709
710 /****************************************************************************
711   send an null session message to a fd
712 ****************************************************************************/
713
714 BOOL send_null_session_msg(int fd)
715 {
716   ssize_t ret;
717   uint32 blank = 0;
718   size_t len = 4;
719   size_t nwritten=0;
720   char *buffer = (char *)&blank;
721
722   while (nwritten < len)
723   {
724     ret = write_socket(fd,buffer+nwritten,len - nwritten);
725     if (ret <= 0)
726     {
727       DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
728       close_sockets();
729       exit(1);
730     }
731     nwritten += ret;
732   }
733
734   DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n"));
735   return True;
736 }
737
738 /****************************************************************************
739   send an smb to a fd 
740 ****************************************************************************/
741
742 BOOL send_smb(int fd,char *buffer)
743 {
744   size_t len;
745   size_t nwritten=0;
746   ssize_t ret;
747   len = smb_len(buffer) + 4;
748
749   while (nwritten < len)
750   {
751     ret = write_socket(fd,buffer+nwritten,len - nwritten);
752     if (ret <= 0)
753     {
754       DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
755       close_sockets();
756       exit(1);
757     }
758     nwritten += ret;
759   }
760
761   return True;
762 }
763
764 /****************************************************************************
765 send a single packet to a port on another machine
766 ****************************************************************************/
767
768 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
769 {
770   BOOL ret;
771   int out_fd;
772   struct sockaddr_in sock_out;
773
774   if (passive)
775     return(True);
776
777   /* create a socket to write to */
778   out_fd = socket(AF_INET, type, 0);
779   if (out_fd == -1) 
780     {
781       DEBUG(0,("socket failed"));
782       return False;
783     }
784
785   /* set the address and port */
786   memset((char *)&sock_out,'\0',sizeof(sock_out));
787   putip((char *)&sock_out.sin_addr,(char *)&ip);
788   sock_out.sin_port = htons( port );
789   sock_out.sin_family = AF_INET;
790   
791   if (DEBUGLEVEL > 0)
792     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
793              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
794         
795   /* send it */
796   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
797
798   if (!ret)
799     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
800              inet_ntoa(ip),port,strerror(errno)));
801
802   close(out_fd);
803   return(ret);
804 }
805
806 /****************************************************************************
807 open a socket of the specified type, port and address for incoming data
808 ****************************************************************************/
809
810 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
811 {
812   struct hostent *hp;
813   struct sockaddr_in sock;
814   pstring host_name;
815   int res;
816
817   /* get my host name */
818   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
819     { DEBUG(0,("gethostname failed\n")); return -1; } 
820
821   /* get host info */
822   if ((hp = Get_Hostbyname(host_name)) == 0) 
823     {
824       DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
825       return -1;
826     }
827   
828   memset((char *)&sock,'\0',sizeof(sock));
829   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
830
831 #ifdef HAVE_SOCK_SIN_LEN
832   sock.sin_len = sizeof(sock);
833 #endif
834   sock.sin_port = htons( port );
835   sock.sin_family = hp->h_addrtype;
836   sock.sin_addr.s_addr = socket_addr;
837   res = socket(hp->h_addrtype, type, 0);
838   if (res == -1) 
839     { DEBUG(0,("socket failed\n")); return -1; }
840
841   {
842     int val=1;
843         if(rebind)
844                 val=1;
845         else
846                 val=0;
847     if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1)
848                 DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n",
849                         val, port, strerror(errno) ));
850 #ifdef SO_REUSEPORT
851     if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1)
852                 DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n",
853                         val, port, strerror(errno) ));
854 #endif /* SO_REUSEPORT */
855   }
856
857   /* now we've got a socket - we need to bind it */
858   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
859     { 
860       if (port) {
861         if (port == SMB_PORT || port == NMB_PORT)
862           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
863                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
864         close(res); 
865
866         if (dlevel > 0 && port < 1000)
867           port = 7999;
868
869         if (port >= 1000 && port < 9000)
870           return(open_socket_in(type,port+1,dlevel,socket_addr,rebind));
871       }
872
873       return(-1); 
874     }
875   DEBUG(3,("bind succeeded on port %d\n",port));
876
877   return res;
878 }
879
880 /****************************************************************************
881   create an outgoing socket. timeout is in milliseconds.
882   **************************************************************************/
883
884 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
885 {
886   struct sockaddr_in sock_out;
887   int res,ret;
888   int connect_loop = 250; /* 250 milliseconds */
889   int loops = (timeout) / connect_loop;
890
891   /* create a socket to write to */
892   res = socket(PF_INET, type, 0);
893   if (res == -1) 
894     { DEBUG(0,("socket error\n")); return -1; }
895
896   if (type != SOCK_STREAM) return(res);
897   
898   memset((char *)&sock_out,'\0',sizeof(sock_out));
899   putip((char *)&sock_out.sin_addr,(char *)addr);
900   
901   sock_out.sin_port = htons( port );
902   sock_out.sin_family = PF_INET;
903
904   /* set it non-blocking */
905   set_blocking(res,False);
906
907   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
908   
909   /* and connect it to the destination */
910 connect_again:
911   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
912
913   /* Some systems return EAGAIN when they mean EINPROGRESS */
914   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
915         errno == EAGAIN) && loops--) {
916     msleep(connect_loop);
917     goto connect_again;
918   }
919
920   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
921          errno == EAGAIN)) {
922       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
923       close(res);
924       return -1;
925   }
926
927 #ifdef EISCONN
928   if (ret < 0 && errno == EISCONN) {
929     errno = 0;
930     ret = 0;
931   }
932 #endif
933
934   if (ret < 0) {
935     DEBUG(1,("error connecting to %s:%d (%s)\n",
936              inet_ntoa(*addr),port,strerror(errno)));
937     close(res);
938     return -1;
939   }
940
941   /* set it blocking again */
942   set_blocking(res,True);
943
944   return res;
945 }
946
947
948 /*******************************************************************
949  Reset the 'done' variables so after a client process is created
950  from a fork call these calls will be re-done. This should be
951  expanded if more variables need reseting.
952  ******************************************************************/
953
954 static BOOL global_client_name_done = False;
955 static BOOL global_client_addr_done = False;
956
957 void reset_globals_after_fork(void)
958 {
959   global_client_name_done = False;
960   global_client_addr_done = False;
961
962   /*
963    * Re-seed the random crypto generator, so all smbd's
964    * started from the same parent won't generate the same
965    * sequence.
966    */
967   {
968     unsigned char dummy;
969     generate_random_buffer( &dummy, 1, True);
970   } 
971 }
972  
973 /*******************************************************************
974  return the DNS name of the client 
975  ******************************************************************/
976
977 char *client_name(int fd)
978 {
979         struct sockaddr sa;
980         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
981         int     length = sizeof(sa);
982         static pstring name_buf;
983         struct hostent *hp;
984         static int last_fd=-1;
985         
986         if (global_client_name_done && last_fd == fd) 
987                 return name_buf;
988         
989         last_fd = fd;
990         global_client_name_done = False;
991         
992         pstrcpy(name_buf,"UNKNOWN");
993         
994         if (fd == -1) {
995                 return name_buf;
996         }
997         
998         if (getpeername(fd, &sa, &length) < 0) {
999                 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
1000                 return name_buf;
1001         }
1002         
1003         /* Look up the remote host name. */
1004         if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
1005                                 sizeof(sockin->sin_addr),
1006                                 AF_INET)) == 0) {
1007                 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
1008                 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
1009         } else {
1010                 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
1011                 if (!matchname(name_buf, sockin->sin_addr)) {
1012                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
1013                         pstrcpy(name_buf,"UNKNOWN");
1014                 }
1015         }
1016         global_client_name_done = True;
1017         return name_buf;
1018 }
1019
1020 /*******************************************************************
1021  return the IP addr of the client as a string 
1022  ******************************************************************/
1023
1024 char *client_addr(int fd)
1025 {
1026         struct sockaddr sa;
1027         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
1028         int     length = sizeof(sa);
1029         static fstring addr_buf;
1030         static int last_fd = -1;
1031
1032         if (global_client_addr_done && fd == last_fd) 
1033                 return addr_buf;
1034
1035         last_fd = fd;
1036         global_client_addr_done = False;
1037
1038         fstrcpy(addr_buf,"0.0.0.0");
1039
1040         if (fd == -1) {
1041                 return addr_buf;
1042         }
1043         
1044         if (getpeername(fd, &sa, &length) < 0) {
1045                 DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
1046                 return addr_buf;
1047         }
1048         
1049         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
1050         
1051         global_client_addr_done = True;
1052         return addr_buf;
1053 }
1054
1055 /*******************************************************************
1056  opens and connects to a unix pipe socket
1057  ******************************************************************/
1058 int open_pipe_sock(char *path)
1059 {
1060         int sock;
1061         struct sockaddr_un sa;
1062
1063         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1064
1065         if (sock < 0)
1066         {
1067                 DEBUG(0, ("unix socket open failed\n"));
1068                 return sock;
1069         }
1070
1071         ZERO_STRUCT(sa);
1072         sa.sun_family = AF_UNIX;
1073         safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
1074
1075         DEBUG(10, ("socket open succeeded.  file name: %s\n", sa.sun_path));
1076
1077         if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
1078         {
1079                 DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
1080                 close(sock);
1081                 return -1;
1082         }
1083
1084         return sock;
1085 }
1086
1087 int create_pipe_socket(char *dir, int dir_perms,
1088                                 char *path, int path_perms)
1089 {
1090         int s;
1091         struct sockaddr_un sa;
1092
1093         DEBUG(0,("create_pipe_socket: %s %d %s %d\n",
1094                    dir, dir_perms, path, path_perms));
1095
1096         DEBUG(0,("*** RACE CONDITION.  PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n"));
1097
1098         mkdir(dir, dir_perms);
1099
1100         if (chmod(dir, dir_perms) < 0)
1101         {
1102                 DEBUG(0, ("chmod on %s failed\n", dir));
1103                 return -1;
1104         }
1105
1106         if (!remove(path))
1107         {
1108                 DEBUG(0, ("remove on %s failed\n", path));
1109         }
1110                 
1111         /* start listening on unix socket */
1112         s = socket(AF_UNIX, SOCK_STREAM, 0);
1113
1114         if (s < 0)
1115         {
1116                 DEBUG(0, ("socket open failed\n"));
1117                 return -1;
1118         }
1119
1120         ZERO_STRUCT(sa);
1121         sa.sun_family = AF_UNIX;
1122         safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
1123
1124         if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
1125         {
1126                 DEBUG(0, ("socket bind to %s failed\n", sa.sun_path));
1127                 close(s);
1128                 remove(path);
1129                 return -1;
1130         }
1131
1132         if (s == -1)
1133         {
1134                 DEBUG(0,("bind failed\n"));
1135                 remove(path);
1136                 return -1;
1137         }
1138
1139         if (path_perms != 0)
1140         {
1141                 chmod(path, path_perms);
1142         }
1143
1144         if (listen(s, 5) == -1)
1145         {
1146                 DEBUG(0,("listen failed\n"));
1147                 return -1;
1148         }
1149
1150         DEBUG(5,("unix socket opened: %s\n", path));
1151
1152         return s;
1153 }