r1766: we do not have smb_read_error in samba4
[samba.git] / source4 / lib / util_sock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Tim Potter      2000-2001
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
25 /****************************************************************************
26  Determine if a file descriptor is in fact a socket.
27 ****************************************************************************/
28 BOOL is_a_socket(int fd)
29 {
30         int v,l;
31         l = sizeof(int);
32         return getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0;
33 }
34
35 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
36
37 typedef struct smb_socket_option {
38         const char *name;
39         int level;
40         int option;
41         int value;
42         int opttype;
43 } smb_socket_option;
44
45 static const smb_socket_option socket_options[] = {
46   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
47   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
48   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
49 #ifdef TCP_NODELAY
50   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
51 #endif
52 #ifdef IPTOS_LOWDELAY
53   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
54 #endif
55 #ifdef IPTOS_THROUGHPUT
56   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
57 #endif
58 #ifdef SO_REUSEPORT
59   {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},
60 #endif
61 #ifdef SO_SNDBUF
62   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
63 #endif
64 #ifdef SO_RCVBUF
65   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
66 #endif
67 #ifdef SO_SNDLOWAT
68   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
69 #endif
70 #ifdef SO_RCVLOWAT
71   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
72 #endif
73 #ifdef SO_SNDTIMEO
74   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
75 #endif
76 #ifdef SO_RCVTIMEO
77   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
78 #endif
79   {NULL,0,0,0,0}};
80
81 /****************************************************************************
82  Print socket options.
83 ****************************************************************************/
84
85 static void print_socket_options(int s)
86 {
87         int value, vlen = 4;
88         const smb_socket_option *p = &socket_options[0];
89
90         for (; p->name != NULL; p++) {
91                 if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {
92                         DEBUG(5,("Could not test socket option %s.\n", p->name));
93                 } else {
94                         DEBUG(5,("socket option %s = %d\n",p->name,value));
95                 }
96         }
97  }
98
99 /****************************************************************************
100  Set user socket options.
101 ****************************************************************************/
102
103 void set_socket_options(int fd, const char *options)
104 {
105         fstring tok;
106
107         while (next_token(&options,tok," \t,", sizeof(tok))) {
108                 int ret=0,i;
109                 int value = 1;
110                 char *p;
111                 BOOL got_value = False;
112
113                 if ((p = strchr_m(tok,'='))) {
114                         *p = 0;
115                         value = atoi(p+1);
116                         got_value = True;
117                 }
118
119                 for (i=0;socket_options[i].name;i++)
120                         if (strequal(socket_options[i].name,tok))
121                                 break;
122
123                 if (!socket_options[i].name) {
124                         DEBUG(0,("Unknown socket option %s\n",tok));
125                         continue;
126                 }
127
128                 switch (socket_options[i].opttype) {
129                 case OPT_BOOL:
130                 case OPT_INT:
131                         ret = setsockopt(fd,socket_options[i].level,
132                                                 socket_options[i].option,(char *)&value,sizeof(int));
133                         break;
134
135                 case OPT_ON:
136                         if (got_value)
137                                 DEBUG(0,("syntax error - %s does not take a value\n",tok));
138
139                         {
140                                 int on = socket_options[i].value;
141                                 ret = setsockopt(fd,socket_options[i].level,
142                                                         socket_options[i].option,(char *)&on,sizeof(int));
143                         }
144                         break;    
145                 }
146       
147                 if (ret != 0)
148                         DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
149         }
150
151         print_socket_options(fd);
152 }
153
154 /****************************************************************************
155  Read from a socket.
156 ****************************************************************************/
157
158 ssize_t read_udp_socket(int fd, char *buf, size_t len, 
159                         struct in_addr *from_addr, int *from_port)
160 {
161         ssize_t ret;
162         struct sockaddr_in sock;
163         socklen_t socklen = sizeof(sock);
164
165         ret = (ssize_t)sys_recvfrom(fd,buf,len, 0, (struct sockaddr *)&sock, &socklen);
166         if (ret <= 0) {
167                 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
168                 return 0;
169         }
170
171         if (from_addr) {
172                 *from_addr = sock.sin_addr;
173         }
174         if (from_port) {
175                 *from_port = ntohs(sock.sin_port);
176         }
177
178         return ret;
179 }
180
181
182 /****************************************************************************
183   read data from the client, reading exactly N bytes. 
184 ****************************************************************************/
185 ssize_t read_data(int fd, char *buffer, size_t N)
186 {
187         ssize_t ret;
188         size_t total=0;  
189  
190         if (fd == -1) {
191                 errno = EIO;
192                 return -1;
193         }
194
195         while (total < N) {
196                 ret = sys_read(fd,buffer + total,N - total);
197                 if (ret == 0) {
198                         return total;
199                 }
200                 if (ret == -1) {
201                         if (total == 0) {
202                                 return -1;
203                         }
204                         return total;
205                 }
206                 total += ret;
207         }
208         return (ssize_t)total;
209 }
210
211
212 /****************************************************************************
213  Write data to a fd.
214 ****************************************************************************/
215 ssize_t write_data(int fd, const char *buffer, size_t N)
216 {
217         size_t total=0;
218         ssize_t ret;
219
220         if (fd == -1) {
221                 errno = EIO;
222                 return -1;
223         }
224
225         while (total < N) {
226                 ret = sys_write(fd, buffer + total, N - total);
227                 if (ret == -1) {
228                         if (total == 0) {
229                                 return -1;
230                         }
231                         return total;
232                 }
233                 if (ret == 0) {
234                         return total;
235                 }
236
237                 total += ret;
238         }
239         return (ssize_t)total;
240 }
241
242 /****************************************************************************
243  Check the timeout. 
244 ****************************************************************************/
245
246 static BOOL timeout_until(struct timeval *timeout,
247                           const struct timeval *endtime)
248 {
249         struct timeval now;
250
251         GetTimeOfDay(&now);
252
253         if ((now.tv_sec > endtime->tv_sec) ||
254             ((now.tv_sec == endtime->tv_sec) &&
255              (now.tv_usec > endtime->tv_usec)))
256                 return False;
257
258         timeout->tv_sec = endtime->tv_sec - now.tv_sec;
259         timeout->tv_usec = endtime->tv_usec - now.tv_usec;
260         return True;
261 }
262
263
264 /****************************************************************************
265  Read data from the client, reading exactly N bytes, with timeout. 
266 ****************************************************************************/
267
268 ssize_t read_data_until(int fd,char *buffer,size_t N,
269                         const struct timeval *endtime)
270 {
271         ssize_t ret;
272         size_t total=0;  
273  
274         while (total < N) {
275
276                 if (endtime != NULL) {
277                         fd_set r_fds;
278                         struct timeval timeout;
279                         int res;
280
281                         FD_ZERO(&r_fds);
282                         FD_SET(fd, &r_fds);
283
284                         if (!timeout_until(&timeout, endtime))
285                                 return -1;
286
287                         res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout);
288                         if (res <= 0)
289                                 return -1;
290                 }
291
292                 ret = sys_read(fd,buffer + total,N - total);
293
294                 if (ret == 0) {
295                         DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
296                         return 0;
297                 }
298
299                 if (ret == -1) {
300                         DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
301                         return -1;
302                 }
303                 total += ret;
304         }
305         return (ssize_t)total;
306 }
307
308 /****************************************************************************
309  Write data to a fd with timeout.
310 ****************************************************************************/
311
312 ssize_t write_data_until(int fd,char *buffer,size_t N,
313                          const struct timeval *endtime)
314 {
315         size_t total=0;
316         ssize_t ret;
317
318         while (total < N) {
319
320                 if (endtime != NULL) {
321                         fd_set w_fds;
322                         struct timeval timeout;
323                         int res;
324
325                         FD_ZERO(&w_fds);
326                         FD_SET(fd, &w_fds);
327
328                         if (!timeout_until(&timeout, endtime))
329                                 return -1;
330
331                         res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout);
332                         if (res <= 0)
333                                 return -1;
334                 }
335
336                 ret = sys_write(fd,buffer + total,N - total);
337
338                 if (ret == -1) {
339                         DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
340                         return -1;
341                 }
342                 if (ret == 0)
343                         return total;
344
345                 total += ret;
346         }
347         return (ssize_t)total;
348 }
349
350
351 /****************************************************************************
352 send a keepalive packet (rfc1002)
353 ****************************************************************************/
354 BOOL send_nbt_keepalive(int sock_fd)
355 {
356         uint8_t buf[4];
357
358         buf[0] = SMBkeepalive;
359         buf[1] = buf[2] = buf[3] = 0;
360
361         return write_data(sock_fd,(char *)buf,4) == 4;
362 }
363
364
365 /****************************************************************************
366  Open a socket of the specified type, port, and address for incoming data.
367 ****************************************************************************/
368 int open_socket_in( int type, int port, int dlevel, uint32_t socket_addr, BOOL rebind )
369 {
370         struct sockaddr_in sock;
371         int res;
372
373         memset( (char *)&sock, '\0', sizeof(sock) );
374
375 #ifdef HAVE_SOCK_SIN_LEN
376         sock.sin_len         = sizeof(sock);
377 #endif
378         sock.sin_port        = htons( port );
379         sock.sin_family      = AF_INET;
380         sock.sin_addr.s_addr = socket_addr;
381
382         res = socket( AF_INET, type, 0 );
383         if( res == -1 ) {
384                 DEBUG(0,("open_socket_in(): socket() call failed: %s\n", strerror(errno)));
385                 return -1;
386         }
387
388         /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
389         {
390                 int val = rebind ? 1 : 0;
391                 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
392 #ifdef SO_REUSEPORT
393                 setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val));
394 #endif
395         }
396
397         /* now we've got a socket - we need to bind it */
398         if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
399                 DEBUG(0,("bind failed on port %d - %s\n", port, strerror(errno)));
400                 close( res ); 
401                 return( -1 ); 
402         }
403
404         DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
405
406         return( res );
407  }
408
409
410 /****************************************************************************
411   create an outgoing socket. timeout is in milliseconds.
412   **************************************************************************/
413 int open_socket_out(int type, struct in_addr *addr, int port, int timeout)
414 {
415         struct sockaddr_in sock_out;
416         int res,ret;
417         int connect_loop = 250; /* 250 milliseconds */
418         int loops = (timeout) / connect_loop;
419
420         /* create a socket to write to */
421         res = socket(PF_INET, type, 0);
422         if (res == -1) 
423         { DEBUG(0,("socket error\n")); return -1; }
424         
425         if (type != SOCK_STREAM) return(res);
426         
427         memset((char *)&sock_out,'\0',sizeof(sock_out));
428         putip((char *)&sock_out.sin_addr,(char *)addr);
429         
430         sock_out.sin_port = htons( port );
431         sock_out.sin_family = PF_INET;
432         
433         /* set it non-blocking */
434         set_blocking(res,False);
435         
436         DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
437         
438         /* and connect it to the destination */
439 connect_again:
440         ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
441         
442         /* Some systems return EAGAIN when they mean EINPROGRESS */
443         if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
444                         errno == EAGAIN) && loops--) {
445                 msleep(connect_loop);
446                 goto connect_again;
447         }
448         
449         if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
450                         errno == EAGAIN)) {
451                 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
452                 close(res);
453                 return -1;
454         }
455         
456 #ifdef EISCONN
457         if (ret < 0 && errno == EISCONN) {
458                 errno = 0;
459                 ret = 0;
460         }
461 #endif
462         
463         if (ret < 0) {
464                 DEBUG(2,("error connecting to %s:%d (%s)\n",
465                          inet_ntoa(*addr),port,strerror(errno)));
466                 close(res);
467                 return -1;
468         }
469         
470         /* set it blocking again */
471         set_blocking(res,True);
472         
473         return res;
474 }
475
476 /*
477   open a connected UDP socket to host on port
478 */
479 int open_udp_socket(const char *host, int port)
480 {
481         int type = SOCK_DGRAM;
482         struct sockaddr_in sock_out;
483         int res;
484         struct in_addr *addr;
485         TALLOC_CTX *mem_ctx;
486
487         mem_ctx = talloc_init("open_udp_socket");
488         if (!mem_ctx) {
489                 return -1;
490         }
491         addr = interpret_addr2(mem_ctx, host);
492
493         res = socket(PF_INET, type, 0);
494         if (res == -1) {
495                 return -1;
496         }
497
498         memset((char *)&sock_out,'\0',sizeof(sock_out));
499         putip((char *)&sock_out.sin_addr,(char *)addr);
500         sock_out.sin_port = htons(port);
501         sock_out.sin_family = PF_INET;
502         
503         talloc_destroy(mem_ctx);
504
505         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
506                 close(res);
507                 return -1;
508         }
509
510         return res;
511 }
512
513
514 /*******************************************************************
515  matchname - determine if host name matches IP address. Used to
516  confirm a hostname lookup to prevent spoof attacks
517  ******************************************************************/
518 static BOOL matchname(char *remotehost, struct in_addr addr)
519 {
520         struct hostent *hp;
521         int     i;
522         
523         if ((hp = sys_gethostbyname(remotehost)) == 0) {
524                 DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n", remotehost));
525                 return False;
526         } 
527
528         /*
529          * Make sure that gethostbyname() returns the "correct" host name.
530          * Unfortunately, gethostbyname("localhost") sometimes yields
531          * "localhost.domain". Since the latter host name comes from the
532          * local DNS, we just have to trust it (all bets are off if the local
533          * DNS is perverted). We always check the address list, though.
534          */
535         
536         if (strcasecmp(remotehost, hp->h_name)
537             && strcasecmp(remotehost, "localhost")) {
538                 DEBUG(0,("host name/name mismatch: %s != %s\n",
539                          remotehost, hp->h_name));
540                 return False;
541         }
542         
543         /* Look up the host address in the address list we just got. */
544         for (i = 0; hp->h_addr_list[i]; i++) {
545                 if (memcmp(hp->h_addr_list[i], (char *) & addr, sizeof(addr)) == 0)
546                         return True;
547         }
548         
549         /*
550          * The host name does not map to the original host address. Perhaps
551          * someone has compromised a name server. More likely someone botched
552          * it, but that could be dangerous, too.
553          */
554         
555         DEBUG(0,("host name/address mismatch: %s != %s\n",
556                  inet_ntoa(addr), hp->h_name));
557         return False;
558 }
559
560  
561 /*******************************************************************
562  return the DNS name of the remote end of a socket
563  ******************************************************************/
564 char *get_socket_name(TALLOC_CTX *mem_ctx, int fd, BOOL force_lookup)
565 {
566         char *name_buf;
567         struct hostent *hp;
568         struct in_addr addr;
569         char *p;
570
571         /* reverse lookups can be *very* expensive, and in many
572            situations won't work because many networks don't link dhcp
573            with dns. To avoid the delay we avoid the lookup if
574            possible */
575         if (!lp_hostname_lookups() && (force_lookup == False)) {
576                 return get_socket_addr(mem_ctx, fd);
577         }
578         
579         p = get_socket_addr(mem_ctx, fd);
580
581         name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
582         if (fd == -1) return name_buf;
583
584         addr = *interpret_addr2(mem_ctx, p);
585         
586         /* Look up the remote host name. */
587         if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) {
588                 DEBUG(1,("Gethostbyaddr failed for %s\n",p));
589                 name_buf = talloc_strdup(mem_ctx, p);
590         } else {
591                 name_buf = talloc_strdup(mem_ctx, (char *)hp->h_name);
592                 if (!matchname(name_buf, addr)) {
593                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
594                         name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
595                 }
596         }
597
598         alpha_strcpy(name_buf, name_buf, "_-.", strlen(name_buf)+1);
599         if (strstr(name_buf,"..")) {
600                 name_buf = talloc_strdup(mem_ctx, "UNKNOWN");
601         }
602
603         return name_buf;
604 }
605
606 /*******************************************************************
607  return the IP addr of the remote end of a socket as a string 
608  ******************************************************************/
609 char *get_socket_addr(TALLOC_CTX *mem_ctx, int fd)
610 {
611         struct sockaddr sa;
612         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
613         int     length = sizeof(sa);
614
615         if (fd == -1 || getpeername(fd, &sa, &length) == -1) {
616                 return talloc_strdup(mem_ctx, "0.0.0.0");
617         }
618         
619         return talloc_strdup(mem_ctx, (char *)inet_ntoa(sockin->sin_addr));
620 }
621
622
623
624 /*******************************************************************
625 this is like socketpair but uses tcp. It is used by the Samba
626 regression test code
627 The function guarantees that nobody else can attach to the socket,
628 or if they do that this function fails and the socket gets closed
629 returns 0 on success, -1 on failure
630 the resulting file descriptors are symmetrical
631  ******************************************************************/
632 static int socketpair_tcp(int fd[2])
633 {
634         int listener;
635         struct sockaddr_in sock;
636         struct sockaddr_in sock2;
637         socklen_t socklen = sizeof(sock);
638         int connect_done = 0;
639         
640         fd[0] = fd[1] = listener = -1;
641
642         memset(&sock, 0, sizeof(sock));
643         
644         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
645
646         memset(&sock2, 0, sizeof(sock2));
647 #ifdef HAVE_SOCK_SIN_LEN
648         sock2.sin_len = sizeof(sock2);
649 #endif
650         sock2.sin_family = PF_INET;
651
652         bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
653
654         if (listen(listener, 1) != 0) goto failed;
655
656         if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
657
658         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
659
660         set_blocking(fd[1], 0);
661
662         sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
663
664         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
665                 if (errno != EINPROGRESS) goto failed;
666         } else {
667                 connect_done = 1;
668         }
669
670         if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
671
672         close(listener);
673         if (connect_done == 0) {
674                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
675                     && errno != EISCONN) goto failed;
676         }
677
678         set_blocking(fd[1], 1);
679
680         /* all OK! */
681         return 0;
682
683  failed:
684         if (fd[0] != -1) close(fd[0]);
685         if (fd[1] != -1) close(fd[1]);
686         if (listener != -1) close(listener);
687         return -1;
688 }
689
690
691 /*******************************************************************
692 run a program on a local tcp socket, this is used to launch smbd
693 when regression testing
694 the return value is a socket which is attached to a subprocess
695 running "prog". stdin and stdout are attached. stderr is left
696 attached to the original stderr
697  ******************************************************************/
698 int sock_exec(const char *prog)
699 {
700         int fd[2];
701         if (socketpair_tcp(fd) != 0) {
702                 DEBUG(0,("socketpair_tcp failed (%s)\n", strerror(errno)));
703                 return -1;
704         }
705         if (fork() == 0) {
706                 close(fd[0]);
707                 close(0);
708                 close(1);
709                 dup(fd[1]);
710                 dup(fd[1]);
711                 exit(system(prog));
712         }
713         close(fd[1]);
714         return fd[0];
715 }
716
717
718 /*
719   determine if a packet is pending for receive on a socket
720 */
721 BOOL socket_pending(int fd)
722 {
723         fd_set fds;
724         int selrtn;
725         struct timeval timeout;
726
727         FD_ZERO(&fds);
728         FD_SET(fd,&fds);
729         
730         /* immediate timeout */
731         timeout.tv_sec = 0;
732         timeout.tv_usec = 0;
733
734         /* yes, this is supposed to be a normal select not a sys_select() */
735         selrtn = select(fd+1,&fds,NULL,NULL,&timeout);
736                 
737         if (selrtn == 1) {
738                 /* the fd is readable */
739                 return True;
740         }
741
742         return False;
743 }