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