Merge branch 'master' of ctdb into 'master' of samba
[metze/samba/wip.git] / source3 / 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    Copyright (C) Jeremy Allison  1992-2007
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "memcache.h"
25 #include "../lib/async_req/async_sock.h"
26 #include "../lib/util/select.h"
27 #include "lib/socket/interfaces.h"
28 #include "../lib/util/tevent_unix.h"
29 #include "../lib/util/tevent_ntstatus.h"
30 #include "../lib/tsocket/tsocket.h"
31
32 const char *client_addr(int fd, char *addr, size_t addrlen)
33 {
34         return get_peer_addr(fd,addr,addrlen);
35 }
36
37 #if 0
38 /* Not currently used. JRA. */
39 int client_socket_port(int fd)
40 {
41         return get_socket_port(fd);
42 }
43 #endif
44
45 /****************************************************************************
46  Determine if a file descriptor is in fact a socket.
47 ****************************************************************************/
48
49 bool is_a_socket(int fd)
50 {
51         int v;
52         socklen_t l;
53         l = sizeof(int);
54         return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
55 }
56
57 /****************************************************************************
58  Read from a socket.
59 ****************************************************************************/
60
61 ssize_t read_udp_v4_socket(int fd,
62                         char *buf,
63                         size_t len,
64                         struct sockaddr_storage *psa)
65 {
66         ssize_t ret;
67         socklen_t socklen = sizeof(*psa);
68         struct sockaddr_in *si = (struct sockaddr_in *)psa;
69
70         memset((char *)psa,'\0',socklen);
71
72         ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
73                         (struct sockaddr *)psa,&socklen);
74         if (ret <= 0) {
75                 /* Don't print a low debug error for a non-blocking socket. */
76                 if (errno == EAGAIN) {
77                         DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
78                 } else {
79                         DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
80                                 strerror(errno)));
81                 }
82                 return 0;
83         }
84
85         if (psa->ss_family != AF_INET) {
86                 DEBUG(2,("read_udp_v4_socket: invalid address family %d "
87                         "(not IPv4)\n", (int)psa->ss_family));
88                 return 0;
89         }
90
91         DEBUG(10,("read_udp_v4_socket: ip %s port %d read: %lu\n",
92                         inet_ntoa(si->sin_addr),
93                         si->sin_port,
94                         (unsigned long)ret));
95
96         return ret;
97 }
98
99 /****************************************************************************
100  Read data from a file descriptor with a timout in msec.
101  mincount = if timeout, minimum to read before returning
102  maxcount = number to be read.
103  time_out = timeout in milliseconds
104  NB. This can be called with a non-socket fd, don't change
105  sys_read() to sys_recv() or other socket call.
106 ****************************************************************************/
107
108 NTSTATUS read_fd_with_timeout(int fd, char *buf,
109                                   size_t mincnt, size_t maxcnt,
110                                   unsigned int time_out,
111                                   size_t *size_ret)
112 {
113         int pollrtn;
114         ssize_t readret;
115         size_t nread = 0;
116
117         /* just checking .... */
118         if (maxcnt <= 0)
119                 return NT_STATUS_OK;
120
121         /* Blocking read */
122         if (time_out == 0) {
123                 if (mincnt == 0) {
124                         mincnt = maxcnt;
125                 }
126
127                 while (nread < mincnt) {
128                         readret = sys_read(fd, buf + nread, maxcnt - nread);
129
130                         if (readret == 0) {
131                                 DEBUG(5,("read_fd_with_timeout: "
132                                         "blocking read. EOF from client.\n"));
133                                 return NT_STATUS_END_OF_FILE;
134                         }
135
136                         if (readret == -1) {
137                                 return map_nt_error_from_unix(errno);
138                         }
139                         nread += readret;
140                 }
141                 goto done;
142         }
143
144         /* Most difficult - timeout read */
145         /* If this is ever called on a disk file and
146            mincnt is greater then the filesize then
147            system performance will suffer severely as
148            select always returns true on disk files */
149
150         for (nread=0; nread < mincnt; ) {
151                 int revents;
152
153                 pollrtn = poll_intr_one_fd(fd, POLLIN|POLLHUP, time_out,
154                                            &revents);
155
156                 /* Check if error */
157                 if (pollrtn == -1) {
158                         return map_nt_error_from_unix(errno);
159                 }
160
161                 /* Did we timeout ? */
162                 if ((pollrtn == 0) ||
163                     ((revents & (POLLIN|POLLHUP|POLLERR)) == 0)) {
164                         DEBUG(10,("read_fd_with_timeout: timeout read. "
165                                 "select timed out.\n"));
166                         return NT_STATUS_IO_TIMEOUT;
167                 }
168
169                 readret = sys_read(fd, buf+nread, maxcnt-nread);
170
171                 if (readret == 0) {
172                         /* we got EOF on the file descriptor */
173                         DEBUG(5,("read_fd_with_timeout: timeout read. "
174                                 "EOF from client.\n"));
175                         return NT_STATUS_END_OF_FILE;
176                 }
177
178                 if (readret == -1) {
179                         return map_nt_error_from_unix(errno);
180                 }
181
182                 nread += readret;
183         }
184
185  done:
186         /* Return the number we got */
187         if (size_ret) {
188                 *size_ret = nread;
189         }
190         return NT_STATUS_OK;
191 }
192
193 /****************************************************************************
194  Read data from an fd, reading exactly N bytes.
195  NB. This can be called with a non-socket fd, don't add dependencies
196  on socket calls.
197 ****************************************************************************/
198
199 NTSTATUS read_data(int fd, char *buffer, size_t N)
200 {
201         return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
202 }
203
204 /****************************************************************************
205  Write all data from an iov array
206  NB. This can be called with a non-socket fd, don't add dependencies
207  on socket calls.
208 ****************************************************************************/
209
210 ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
211 {
212         int i;
213         size_t to_send;
214         ssize_t thistime;
215         size_t sent;
216         struct iovec *iov_copy, *iov;
217
218         to_send = 0;
219         for (i=0; i<iovcnt; i++) {
220                 to_send += orig_iov[i].iov_len;
221         }
222
223         thistime = sys_writev(fd, orig_iov, iovcnt);
224         if ((thistime <= 0) || (thistime == to_send)) {
225                 return thistime;
226         }
227         sent = thistime;
228
229         /*
230          * We could not send everything in one call. Make a copy of iov that
231          * we can mess with. We keep a copy of the array start in iov_copy for
232          * the TALLOC_FREE, because we're going to modify iov later on,
233          * discarding elements.
234          */
235
236         iov_copy = (struct iovec *)talloc_memdup(
237                 talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
238
239         if (iov_copy == NULL) {
240                 errno = ENOMEM;
241                 return -1;
242         }
243         iov = iov_copy;
244
245         while (sent < to_send) {
246                 /*
247                  * We have to discard "thistime" bytes from the beginning
248                  * iov array, "thistime" contains the number of bytes sent
249                  * via writev last.
250                  */
251                 while (thistime > 0) {
252                         if (thistime < iov[0].iov_len) {
253                                 char *new_base =
254                                         (char *)iov[0].iov_base + thistime;
255                                 iov[0].iov_base = (void *)new_base;
256                                 iov[0].iov_len -= thistime;
257                                 break;
258                         }
259                         thistime -= iov[0].iov_len;
260                         iov += 1;
261                         iovcnt -= 1;
262                 }
263
264                 thistime = sys_writev(fd, iov, iovcnt);
265                 if (thistime <= 0) {
266                         break;
267                 }
268                 sent += thistime;
269         }
270
271         TALLOC_FREE(iov_copy);
272         return sent;
273 }
274
275 /****************************************************************************
276  Write data to a fd.
277  NB. This can be called with a non-socket fd, don't add dependencies
278  on socket calls.
279 ****************************************************************************/
280
281 ssize_t write_data(int fd, const char *buffer, size_t N)
282 {
283         struct iovec iov;
284
285         iov.iov_base = discard_const_p(void, buffer);
286         iov.iov_len = N;
287         return write_data_iov(fd, &iov, 1);
288 }
289
290 /****************************************************************************
291  Send a keepalive packet (rfc1002).
292 ****************************************************************************/
293
294 bool send_keepalive(int client)
295 {
296         unsigned char buf[4];
297
298         buf[0] = NBSSkeepalive;
299         buf[1] = buf[2] = buf[3] = 0;
300
301         return(write_data(client,(char *)buf,4) == 4);
302 }
303
304 /****************************************************************************
305  Read 4 bytes of a smb packet and return the smb length of the packet.
306  Store the result in the buffer.
307  This version of the function will return a length of zero on receiving
308  a keepalive packet.
309  Timeout is in milliseconds.
310 ****************************************************************************/
311
312 NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf,
313                                           unsigned int timeout,
314                                           size_t *len)
315 {
316         int msg_type;
317         NTSTATUS status;
318
319         status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL);
320
321         if (!NT_STATUS_IS_OK(status)) {
322                 return status;
323         }
324
325         *len = smb_len(inbuf);
326         msg_type = CVAL(inbuf,0);
327
328         if (msg_type == NBSSkeepalive) {
329                 DEBUG(5,("Got keepalive packet\n"));
330         }
331
332         DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len)));
333
334         return NT_STATUS_OK;
335 }
336
337 /****************************************************************************
338  Read an smb from a fd.
339  The timeout is in milliseconds.
340  This function will return on receipt of a session keepalive packet.
341  maxlen is the max number of bytes to return, not including the 4 byte
342  length. If zero it means buflen limit.
343  Doesn't check the MAC on signed packets.
344 ****************************************************************************/
345
346 NTSTATUS receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned int timeout,
347                          size_t maxlen, size_t *p_len)
348 {
349         size_t len;
350         NTSTATUS status;
351
352         status = read_smb_length_return_keepalive(fd,buffer,timeout,&len);
353
354         if (!NT_STATUS_IS_OK(status)) {
355                 DEBUG(0, ("read_fd_with_timeout failed, read "
356                           "error = %s.\n", nt_errstr(status)));
357                 return status;
358         }
359
360         if (len > buflen) {
361                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
362                                         (unsigned long)len));
363                 return NT_STATUS_INVALID_PARAMETER;
364         }
365
366         if(len > 0) {
367                 if (maxlen) {
368                         len = MIN(len,maxlen);
369                 }
370
371                 status = read_fd_with_timeout(
372                         fd, buffer+4, len, len, timeout, &len);
373
374                 if (!NT_STATUS_IS_OK(status)) {
375                         DEBUG(0, ("read_fd_with_timeout failed, read error = "
376                                   "%s.\n", nt_errstr(status)));
377                         return status;
378                 }
379
380                 /* not all of samba3 properly checks for packet-termination
381                  * of strings. This ensures that we don't run off into
382                  * empty space. */
383                 SSVAL(buffer+4,len, 0);
384         }
385
386         *p_len = len;
387         return NT_STATUS_OK;
388 }
389
390 /****************************************************************************
391  Open a socket of the specified type, port, and address for incoming data.
392 ****************************************************************************/
393
394 int open_socket_in(int type,
395                 uint16_t port,
396                 int dlevel,
397                 const struct sockaddr_storage *psock,
398                 bool rebind)
399 {
400         struct sockaddr_storage sock;
401         int res;
402         socklen_t slen = sizeof(struct sockaddr_in);
403
404         sock = *psock;
405
406 #if defined(HAVE_IPV6)
407         if (sock.ss_family == AF_INET6) {
408                 ((struct sockaddr_in6 *)&sock)->sin6_port = htons(port);
409                 slen = sizeof(struct sockaddr_in6);
410         }
411 #endif
412         if (sock.ss_family == AF_INET) {
413                 ((struct sockaddr_in *)&sock)->sin_port = htons(port);
414         }
415
416         res = socket(sock.ss_family, type, 0 );
417         if( res == -1 ) {
418                 if( DEBUGLVL(0) ) {
419                         dbgtext( "open_socket_in(): socket() call failed: " );
420                         dbgtext( "%s\n", strerror( errno ) );
421                 }
422                 return -1;
423         }
424
425         /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
426         {
427                 int val = rebind ? 1 : 0;
428                 if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,
429                                         (char *)&val,sizeof(val)) == -1 ) {
430                         if( DEBUGLVL( dlevel ) ) {
431                                 dbgtext( "open_socket_in(): setsockopt: " );
432                                 dbgtext( "SO_REUSEADDR = %s ",
433                                                 val?"true":"false" );
434                                 dbgtext( "on port %d failed ", port );
435                                 dbgtext( "with error = %s\n", strerror(errno) );
436                         }
437                 }
438 #ifdef SO_REUSEPORT
439                 if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,
440                                         (char *)&val,sizeof(val)) == -1 ) {
441                         if( DEBUGLVL( dlevel ) ) {
442                                 dbgtext( "open_socket_in(): setsockopt: ");
443                                 dbgtext( "SO_REUSEPORT = %s ",
444                                                 val?"true":"false");
445                                 dbgtext( "on port %d failed ", port);
446                                 dbgtext( "with error = %s\n", strerror(errno));
447                         }
448                 }
449 #endif /* SO_REUSEPORT */
450         }
451
452 #ifdef HAVE_IPV6
453         /*
454          * As IPV6_V6ONLY is the default on some systems,
455          * we better try to be consistent and always use it.
456          *
457          * This also avoids using IPv4 via AF_INET6 sockets
458          * and makes sure %I never resolves to a '::ffff:192.168.0.1'
459          * string.
460          */
461         if (sock.ss_family == AF_INET6) {
462                 int val = 1;
463                 int ret;
464
465                 ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
466                                  (const void *)&val, sizeof(val));
467                 if (ret == -1) {
468                         if(DEBUGLVL(0)) {
469                                 dbgtext("open_socket_in(): IPV6_ONLY failed: ");
470                                 dbgtext("%s\n", strerror(errno));
471                         }
472                         close(res);
473                         return -1;
474                 }
475         }
476 #endif
477
478         /* now we've got a socket - we need to bind it */
479         if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
480                 if( DEBUGLVL(dlevel) && (port == NMB_PORT ||
481                                          port == NBT_SMB_PORT ||
482                                          port == TCP_SMB_PORT) ) {
483                         char addr[INET6_ADDRSTRLEN];
484                         print_sockaddr(addr, sizeof(addr),
485                                         &sock);
486                         dbgtext( "bind failed on port %d ", port);
487                         dbgtext( "socket_addr = %s.\n", addr);
488                         dbgtext( "Error = %s\n", strerror(errno));
489                 }
490                 close(res);
491                 return -1;
492         }
493
494         DEBUG( 10, ( "bind succeeded on port %d\n", port ) );
495         return( res );
496  }
497
498 struct open_socket_out_state {
499         int fd;
500         struct tevent_context *ev;
501         struct sockaddr_storage ss;
502         socklen_t salen;
503         uint16_t port;
504         int wait_usec;
505 };
506
507 static void open_socket_out_connected(struct tevent_req *subreq);
508
509 static int open_socket_out_state_destructor(struct open_socket_out_state *s)
510 {
511         if (s->fd != -1) {
512                 close(s->fd);
513         }
514         return 0;
515 }
516
517 /****************************************************************************
518  Create an outgoing socket. timeout is in milliseconds.
519 **************************************************************************/
520
521 struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
522                                         struct tevent_context *ev,
523                                         const struct sockaddr_storage *pss,
524                                         uint16_t port,
525                                         int timeout)
526 {
527         char addr[INET6_ADDRSTRLEN];
528         struct tevent_req *result, *subreq;
529         struct open_socket_out_state *state;
530         NTSTATUS status;
531
532         result = tevent_req_create(mem_ctx, &state,
533                                    struct open_socket_out_state);
534         if (result == NULL) {
535                 return NULL;
536         }
537         state->ev = ev;
538         state->ss = *pss;
539         state->port = port;
540         state->wait_usec = 10000;
541         state->salen = -1;
542
543         state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
544         if (state->fd == -1) {
545                 status = map_nt_error_from_unix(errno);
546                 goto post_status;
547         }
548         talloc_set_destructor(state, open_socket_out_state_destructor);
549
550         if (!tevent_req_set_endtime(
551                     result, ev, timeval_current_ofs_msec(timeout))) {
552                 goto fail;
553         }
554
555 #if defined(HAVE_IPV6)
556         if (pss->ss_family == AF_INET6) {
557                 struct sockaddr_in6 *psa6;
558                 psa6 = (struct sockaddr_in6 *)&state->ss;
559                 psa6->sin6_port = htons(port);
560                 if (psa6->sin6_scope_id == 0
561                     && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
562                         setup_linklocal_scope_id(
563                                 (struct sockaddr *)&(state->ss));
564                 }
565                 state->salen = sizeof(struct sockaddr_in6);
566         }
567 #endif
568         if (pss->ss_family == AF_INET) {
569                 struct sockaddr_in *psa;
570                 psa = (struct sockaddr_in *)&state->ss;
571                 psa->sin_port = htons(port);
572                 state->salen = sizeof(struct sockaddr_in);
573         }
574
575         if (pss->ss_family == AF_UNIX) {
576                 state->salen = sizeof(struct sockaddr_un);
577         }
578
579         print_sockaddr(addr, sizeof(addr), &state->ss);
580         DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
581
582         subreq = async_connect_send(state, state->ev, state->fd,
583                                     (struct sockaddr *)&state->ss,
584                                     state->salen, NULL, NULL, NULL);
585         if ((subreq == NULL)
586             || !tevent_req_set_endtime(
587                     subreq, state->ev,
588                     timeval_current_ofs(0, state->wait_usec))) {
589                 goto fail;
590         }
591         tevent_req_set_callback(subreq, open_socket_out_connected, result);
592         return result;
593
594  post_status:
595         tevent_req_nterror(result, status);
596         return tevent_req_post(result, ev);
597  fail:
598         TALLOC_FREE(result);
599         return NULL;
600 }
601
602 static void open_socket_out_connected(struct tevent_req *subreq)
603 {
604         struct tevent_req *req =
605                 tevent_req_callback_data(subreq, struct tevent_req);
606         struct open_socket_out_state *state =
607                 tevent_req_data(req, struct open_socket_out_state);
608         int ret;
609         int sys_errno;
610
611         ret = async_connect_recv(subreq, &sys_errno);
612         TALLOC_FREE(subreq);
613         if (ret == 0) {
614                 tevent_req_done(req);
615                 return;
616         }
617
618         if (
619 #ifdef ETIMEDOUT
620                 (sys_errno == ETIMEDOUT) ||
621 #endif
622                 (sys_errno == EINPROGRESS) ||
623                 (sys_errno == EALREADY) ||
624                 (sys_errno == EAGAIN)) {
625
626                 /*
627                  * retry
628                  */
629
630                 if (state->wait_usec < 250000) {
631                         state->wait_usec *= 1.5;
632                 }
633
634                 subreq = async_connect_send(state, state->ev, state->fd,
635                                             (struct sockaddr *)&state->ss,
636                                             state->salen, NULL, NULL, NULL);
637                 if (tevent_req_nomem(subreq, req)) {
638                         return;
639                 }
640                 if (!tevent_req_set_endtime(
641                             subreq, state->ev,
642                             timeval_current_ofs_usec(state->wait_usec))) {
643                         tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
644                         return;
645                 }
646                 tevent_req_set_callback(subreq, open_socket_out_connected, req);
647                 return;
648         }
649
650 #ifdef EISCONN
651         if (sys_errno == EISCONN) {
652                 tevent_req_done(req);
653                 return;
654         }
655 #endif
656
657         /* real error */
658         tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
659 }
660
661 NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
662 {
663         struct open_socket_out_state *state =
664                 tevent_req_data(req, struct open_socket_out_state);
665         NTSTATUS status;
666
667         if (tevent_req_is_nterror(req, &status)) {
668                 return status;
669         }
670         *pfd = state->fd;
671         state->fd = -1;
672         return NT_STATUS_OK;
673 }
674
675 /**
676 * @brief open a socket
677 *
678 * @param pss a struct sockaddr_storage defining the address to connect to
679 * @param port to connect to
680 * @param timeout in MILLISECONDS
681 * @param pfd file descriptor returned
682 *
683 * @return NTSTATUS code
684 */
685 NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
686                          int timeout, int *pfd)
687 {
688         TALLOC_CTX *frame = talloc_stackframe();
689         struct tevent_context *ev;
690         struct tevent_req *req;
691         NTSTATUS status = NT_STATUS_NO_MEMORY;
692
693         ev = samba_tevent_context_init(frame);
694         if (ev == NULL) {
695                 goto fail;
696         }
697
698         req = open_socket_out_send(frame, ev, pss, port, timeout);
699         if (req == NULL) {
700                 goto fail;
701         }
702         if (!tevent_req_poll(req, ev)) {
703                 status = NT_STATUS_INTERNAL_ERROR;
704                 goto fail;
705         }
706         status = open_socket_out_recv(req, pfd);
707  fail:
708         TALLOC_FREE(frame);
709         return status;
710 }
711
712 struct open_socket_out_defer_state {
713         struct tevent_context *ev;
714         struct sockaddr_storage ss;
715         uint16_t port;
716         int timeout;
717         int fd;
718 };
719
720 static void open_socket_out_defer_waited(struct tevent_req *subreq);
721 static void open_socket_out_defer_connected(struct tevent_req *subreq);
722
723 struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
724                                               struct tevent_context *ev,
725                                               struct timeval wait_time,
726                                               const struct sockaddr_storage *pss,
727                                               uint16_t port,
728                                               int timeout)
729 {
730         struct tevent_req *req, *subreq;
731         struct open_socket_out_defer_state *state;
732
733         req = tevent_req_create(mem_ctx, &state,
734                                 struct open_socket_out_defer_state);
735         if (req == NULL) {
736                 return NULL;
737         }
738         state->ev = ev;
739         state->ss = *pss;
740         state->port = port;
741         state->timeout = timeout;
742
743         subreq = tevent_wakeup_send(
744                 state, ev,
745                 timeval_current_ofs(wait_time.tv_sec, wait_time.tv_usec));
746         if (subreq == NULL) {
747                 goto fail;
748         }
749         tevent_req_set_callback(subreq, open_socket_out_defer_waited, req);
750         return req;
751  fail:
752         TALLOC_FREE(req);
753         return NULL;
754 }
755
756 static void open_socket_out_defer_waited(struct tevent_req *subreq)
757 {
758         struct tevent_req *req = tevent_req_callback_data(
759                 subreq, struct tevent_req);
760         struct open_socket_out_defer_state *state = tevent_req_data(
761                 req, struct open_socket_out_defer_state);
762         bool ret;
763
764         ret = tevent_wakeup_recv(subreq);
765         TALLOC_FREE(subreq);
766         if (!ret) {
767                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
768                 return;
769         }
770
771         subreq = open_socket_out_send(state, state->ev, &state->ss,
772                                       state->port, state->timeout);
773         if (tevent_req_nomem(subreq, req)) {
774                 return;
775         }
776         tevent_req_set_callback(subreq, open_socket_out_defer_connected, req);
777 }
778
779 static void open_socket_out_defer_connected(struct tevent_req *subreq)
780 {
781         struct tevent_req *req = tevent_req_callback_data(
782                 subreq, struct tevent_req);
783         struct open_socket_out_defer_state *state = tevent_req_data(
784                 req, struct open_socket_out_defer_state);
785         NTSTATUS status;
786
787         status = open_socket_out_recv(subreq, &state->fd);
788         TALLOC_FREE(subreq);
789         if (!NT_STATUS_IS_OK(status)) {
790                 tevent_req_nterror(req, status);
791                 return;
792         }
793         tevent_req_done(req);
794 }
795
796 NTSTATUS open_socket_out_defer_recv(struct tevent_req *req, int *pfd)
797 {
798         struct open_socket_out_defer_state *state = tevent_req_data(
799                 req, struct open_socket_out_defer_state);
800         NTSTATUS status;
801
802         if (tevent_req_is_nterror(req, &status)) {
803                 return status;
804         }
805         *pfd = state->fd;
806         state->fd = -1;
807         return NT_STATUS_OK;
808 }
809
810 /****************************************************************************
811  Open a connected UDP socket to host on port
812 **************************************************************************/
813
814 int open_udp_socket(const char *host, int port)
815 {
816         struct sockaddr_storage ss;
817         int res;
818         socklen_t salen;
819
820         if (!interpret_string_addr(&ss, host, 0)) {
821                 DEBUG(10,("open_udp_socket: can't resolve name %s\n",
822                         host));
823                 return -1;
824         }
825
826         res = socket(ss.ss_family, SOCK_DGRAM, 0);
827         if (res == -1) {
828                 return -1;
829         }
830
831 #if defined(HAVE_IPV6)
832         if (ss.ss_family == AF_INET6) {
833                 struct sockaddr_in6 *psa6;
834                 psa6 = (struct sockaddr_in6 *)&ss;
835                 psa6->sin6_port = htons(port);
836                 if (psa6->sin6_scope_id == 0
837                                 && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
838                         setup_linklocal_scope_id(
839                                 (struct sockaddr *)&ss);
840                 }
841                 salen = sizeof(struct sockaddr_in6);
842         } else 
843 #endif
844         if (ss.ss_family == AF_INET) {
845                 struct sockaddr_in *psa;
846                 psa = (struct sockaddr_in *)&ss;
847                 psa->sin_port = htons(port);
848             salen = sizeof(struct sockaddr_in);
849         } else {
850                 DEBUG(1, ("unknown socket family %d", ss.ss_family));
851                 close(res);
852                 return -1;
853         }
854
855         if (connect(res, (struct sockaddr *)&ss, salen)) {
856                 close(res);
857                 return -1;
858         }
859
860         return res;
861 }
862
863 /*******************************************************************
864  Return the IP addr of the remote end of a socket as a string.
865  Optionally return the struct sockaddr_storage.
866  ******************************************************************/
867
868 static const char *get_peer_addr_internal(int fd,
869                                 char *addr_buf,
870                                 size_t addr_buf_len,
871                                 struct sockaddr *pss,
872                                 socklen_t *plength)
873 {
874         struct sockaddr_storage ss;
875         socklen_t length = sizeof(ss);
876
877         strlcpy(addr_buf,"0.0.0.0",addr_buf_len);
878
879         if (fd == -1) {
880                 return addr_buf;
881         }
882
883         if (pss == NULL) {
884                 pss = (struct sockaddr *)&ss;
885                 plength = &length;
886         }
887
888         if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
889                 int level = (errno == ENOTCONN) ? 2 : 0;
890                 DEBUG(level, ("getpeername failed. Error was %s\n",
891                                strerror(errno)));
892                 return addr_buf;
893         }
894
895         print_sockaddr_len(addr_buf,
896                         addr_buf_len,
897                         pss,
898                         *plength);
899         return addr_buf;
900 }
901
902 /*******************************************************************
903  Matchname - determine if host name matches IP address. Used to
904  confirm a hostname lookup to prevent spoof attacks.
905 ******************************************************************/
906
907 static bool matchname(const char *remotehost,
908                 const struct sockaddr *pss,
909                 socklen_t len)
910 {
911         struct addrinfo *res = NULL;
912         struct addrinfo *ailist = NULL;
913         char addr_buf[INET6_ADDRSTRLEN];
914         bool ret = interpret_string_addr_internal(&ailist,
915                         remotehost,
916                         AI_ADDRCONFIG|AI_CANONNAME);
917
918         if (!ret || ailist == NULL) {
919                 DEBUG(3,("matchname: getaddrinfo failed for "
920                         "name %s [%s]\n",
921                         remotehost,
922                         gai_strerror(ret) ));
923                 return false;
924         }
925
926         /*
927          * Make sure that getaddrinfo() returns the "correct" host name.
928          */
929
930         if (ailist->ai_canonname == NULL ||
931                 (!strequal(remotehost, ailist->ai_canonname) &&
932                  !strequal(remotehost, "localhost"))) {
933                 DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
934                          remotehost,
935                          ailist->ai_canonname ?
936                                  ailist->ai_canonname : "(NULL)"));
937                 freeaddrinfo(ailist);
938                 return false;
939         }
940
941         /* Look up the host address in the address list we just got. */
942         for (res = ailist; res; res = res->ai_next) {
943                 if (!res->ai_addr) {
944                         continue;
945                 }
946                 if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
947                                         (const struct sockaddr *)pss)) {
948                         freeaddrinfo(ailist);
949                         return true;
950                 }
951         }
952
953         /*
954          * The host name does not map to the original host address. Perhaps
955          * someone has compromised a name server. More likely someone botched
956          * it, but that could be dangerous, too.
957          */
958
959         DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
960                 print_sockaddr_len(addr_buf,
961                         sizeof(addr_buf),
962                         pss,
963                         len),
964                  ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
965
966         if (ailist) {
967                 freeaddrinfo(ailist);
968         }
969         return false;
970 }
971
972 /*******************************************************************
973  Deal with the singleton cache.
974 ******************************************************************/
975
976 struct name_addr_pair {
977         struct sockaddr_storage ss;
978         const char *name;
979 };
980
981 /*******************************************************************
982  Lookup a name/addr pair. Returns memory allocated from memcache.
983 ******************************************************************/
984
985 static bool lookup_nc(struct name_addr_pair *nc)
986 {
987         DATA_BLOB tmp;
988
989         ZERO_STRUCTP(nc);
990
991         if (!memcache_lookup(
992                         NULL, SINGLETON_CACHE,
993                         data_blob_string_const_null("get_peer_name"),
994                         &tmp)) {
995                 return false;
996         }
997
998         memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
999         nc->name = (const char *)tmp.data + sizeof(nc->ss);
1000         return true;
1001 }
1002
1003 /*******************************************************************
1004  Save a name/addr pair.
1005 ******************************************************************/
1006
1007 static void store_nc(const struct name_addr_pair *nc)
1008 {
1009         DATA_BLOB tmp;
1010         size_t namelen = strlen(nc->name);
1011
1012         tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
1013         if (!tmp.data) {
1014                 return;
1015         }
1016         memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
1017         memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
1018
1019         memcache_add(NULL, SINGLETON_CACHE,
1020                         data_blob_string_const_null("get_peer_name"),
1021                         tmp);
1022         data_blob_free(&tmp);
1023 }
1024
1025 /*******************************************************************
1026  Return the IP addr of the remote end of a socket as a string.
1027  ******************************************************************/
1028
1029 const char *get_peer_addr(int fd, char *addr, size_t addr_len)
1030 {
1031         return get_peer_addr_internal(fd, addr, addr_len, NULL, NULL);
1032 }
1033
1034 int get_remote_hostname(const struct tsocket_address *remote_address,
1035                         char **name,
1036                         TALLOC_CTX *mem_ctx)
1037 {
1038         char name_buf[MAX_DNS_NAME_LENGTH];
1039         char tmp_name[MAX_DNS_NAME_LENGTH];
1040         struct name_addr_pair nc;
1041         struct sockaddr_storage ss;
1042         ssize_t len;
1043         int rc;
1044
1045         if (!lp_hostname_lookups()) {
1046                 nc.name = tsocket_address_inet_addr_string(remote_address,
1047                                                            mem_ctx);
1048                 if (nc.name == NULL) {
1049                         return -1;
1050                 }
1051
1052                 len = tsocket_address_bsd_sockaddr(remote_address,
1053                                                    (struct sockaddr *) &nc.ss,
1054                                                    sizeof(struct sockaddr_storage));
1055                 if (len < 0) {
1056                         return -1;
1057                 }
1058
1059                 store_nc(&nc);
1060                 lookup_nc(&nc);
1061
1062                 if (nc.name == NULL) {
1063                         *name = talloc_strdup(mem_ctx, "UNKNOWN");
1064                 } else {
1065                         *name = talloc_strdup(mem_ctx, nc.name);
1066                 }
1067                 return 0;
1068         }
1069
1070         lookup_nc(&nc);
1071
1072         ZERO_STRUCT(ss);
1073
1074         len = tsocket_address_bsd_sockaddr(remote_address,
1075                                            (struct sockaddr *) &ss,
1076                                            sizeof(struct sockaddr_storage));
1077         if (len < 0) {
1078                 return -1;
1079         }
1080
1081         /* it might be the same as the last one - save some DNS work */
1082         if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
1083                 if (nc.name == NULL) {
1084                         *name = talloc_strdup(mem_ctx, "UNKNOWN");
1085                 } else {
1086                         *name = talloc_strdup(mem_ctx, nc.name);
1087                 }
1088                 return 0;
1089         }
1090
1091         /* Look up the remote host name. */
1092         rc = sys_getnameinfo((struct sockaddr *) &ss,
1093                              len,
1094                              name_buf,
1095                              sizeof(name_buf),
1096                              NULL,
1097                              0,
1098                              0);
1099         if (rc < 0) {
1100                 char *p;
1101
1102                 p = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1103                 if (p == NULL) {
1104                         return -1;
1105                 }
1106
1107                 DEBUG(1,("getnameinfo failed for %s with error %s\n",
1108                          p,
1109                          gai_strerror(rc)));
1110                 strlcpy(name_buf, p, sizeof(name_buf));
1111
1112                 TALLOC_FREE(p);
1113         } else {
1114                 if (!matchname(name_buf, (struct sockaddr *)&ss, len)) {
1115                         DEBUG(0,("matchname failed on %s\n", name_buf));
1116                         strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1117                 }
1118         }
1119
1120         strlcpy(tmp_name, name_buf, sizeof(tmp_name));
1121         alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
1122         if (strstr(name_buf,"..")) {
1123                 strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
1124         }
1125
1126         nc.name = name_buf;
1127         nc.ss = ss;
1128
1129         store_nc(&nc);
1130         lookup_nc(&nc);
1131
1132         if (nc.name == NULL) {
1133                 *name = talloc_strdup(mem_ctx, "UNKOWN");
1134         } else {
1135                 *name = talloc_strdup(mem_ctx, nc.name);
1136         }
1137
1138         return 0;
1139 }
1140
1141 /*******************************************************************
1142  Create protected unix domain socket.
1143
1144  Some unixes cannot set permissions on a ux-dom-sock, so we
1145  have to make sure that the directory contains the protection
1146  permissions instead.
1147  ******************************************************************/
1148
1149 int create_pipe_sock(const char *socket_dir,
1150                      const char *socket_name,
1151                      mode_t dir_perms)
1152 {
1153 #ifdef HAVE_UNIXSOCKET
1154         struct sockaddr_un sunaddr;
1155         bool ok;
1156         int sock = -1;
1157         mode_t old_umask;
1158         char *path = NULL;
1159
1160         old_umask = umask(0);
1161
1162         ok = directory_create_or_exist_strict(socket_dir,
1163                                               sec_initial_uid(),
1164                                               dir_perms);
1165         if (!ok) {
1166                 goto out_close;
1167         }
1168
1169         /* Create the socket file */
1170         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1171
1172         if (sock == -1) {
1173                 DEBUG(0, ("create_pipe_sock: socket error %s\n",
1174                         strerror(errno) ));
1175                 goto out_close;
1176         }
1177
1178         if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) {
1179                 goto out_close;
1180         }
1181
1182         unlink(path);
1183         memset(&sunaddr, 0, sizeof(sunaddr));
1184         sunaddr.sun_family = AF_UNIX;
1185         strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
1186
1187         if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1188                 DEBUG(0, ("bind failed on pipe socket %s: %s\n", path,
1189                         strerror(errno)));
1190                 goto out_close;
1191         }
1192
1193         SAFE_FREE(path);
1194
1195         umask(old_umask);
1196         return sock;
1197
1198 out_close:
1199         SAFE_FREE(path);
1200         if (sock != -1)
1201                 close(sock);
1202
1203         umask(old_umask);
1204         return -1;
1205
1206 #else
1207         DEBUG(0, ("create_pipe_sock: No Unix sockets on this system\n"));
1208         return -1;
1209 #endif /* HAVE_UNIXSOCKET */
1210 }
1211
1212 /****************************************************************************
1213  Get my own canonical name, including domain.
1214 ****************************************************************************/
1215
1216 const char *get_mydnsfullname(void)
1217 {
1218         struct addrinfo *res = NULL;
1219         char my_hostname[HOST_NAME_MAX];
1220         bool ret;
1221         DATA_BLOB tmp;
1222
1223         if (memcache_lookup(NULL, SINGLETON_CACHE,
1224                         data_blob_string_const_null("get_mydnsfullname"),
1225                         &tmp)) {
1226                 SMB_ASSERT(tmp.length > 0);
1227                 return (const char *)tmp.data;
1228         }
1229
1230         /* get my host name */
1231         if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
1232                 DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
1233                 return NULL;
1234         }
1235
1236         /* Ensure null termination. */
1237         my_hostname[sizeof(my_hostname)-1] = '\0';
1238
1239         ret = interpret_string_addr_internal(&res,
1240                                 my_hostname,
1241                                 AI_ADDRCONFIG|AI_CANONNAME);
1242
1243         if (!ret || res == NULL) {
1244                 DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
1245                         "name %s [%s]\n",
1246                         my_hostname,
1247                         gai_strerror(ret) ));
1248                 return NULL;
1249         }
1250
1251         /*
1252          * Make sure that getaddrinfo() returns the "correct" host name.
1253          */
1254
1255         if (res->ai_canonname == NULL) {
1256                 DEBUG(3,("get_mydnsfullname: failed to get "
1257                         "canonical name for %s\n",
1258                         my_hostname));
1259                 freeaddrinfo(res);
1260                 return NULL;
1261         }
1262
1263         /* This copies the data, so we must do a lookup
1264          * afterwards to find the value to return.
1265          */
1266
1267         memcache_add(NULL, SINGLETON_CACHE,
1268                         data_blob_string_const_null("get_mydnsfullname"),
1269                         data_blob_string_const_null(res->ai_canonname));
1270
1271         if (!memcache_lookup(NULL, SINGLETON_CACHE,
1272                         data_blob_string_const_null("get_mydnsfullname"),
1273                         &tmp)) {
1274                 tmp = data_blob_talloc(talloc_tos(), res->ai_canonname,
1275                                 strlen(res->ai_canonname) + 1);
1276         }
1277
1278         freeaddrinfo(res);
1279
1280         return (const char *)tmp.data;
1281 }
1282
1283 /************************************************************
1284  Is this my ip address ?
1285 ************************************************************/
1286
1287 static bool is_my_ipaddr(const char *ipaddr_str)
1288 {
1289         struct sockaddr_storage ss;
1290         struct iface_struct *nics;
1291         int i, n;
1292
1293         if (!interpret_string_addr(&ss, ipaddr_str, AI_NUMERICHOST)) {
1294                 return false;
1295         }
1296
1297         if (is_zero_addr(&ss)) {
1298                 return false;
1299         }
1300
1301         if (ismyaddr((struct sockaddr *)&ss) ||
1302                         is_loopback_addr((struct sockaddr *)&ss)) {
1303                 return true;
1304         }
1305
1306         n = get_interfaces(talloc_tos(), &nics);
1307         for (i=0; i<n; i++) {
1308                 if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
1309                         TALLOC_FREE(nics);
1310                         return true;
1311                 }
1312         }
1313         TALLOC_FREE(nics);
1314         return false;
1315 }
1316
1317 /************************************************************
1318  Is this my name ?
1319 ************************************************************/
1320
1321 bool is_myname_or_ipaddr(const char *s)
1322 {
1323         TALLOC_CTX *ctx = talloc_tos();
1324         char *name = NULL;
1325         const char *dnsname;
1326         char *servername = NULL;
1327
1328         if (!s) {
1329                 return false;
1330         }
1331
1332         /* Santize the string from '\\name' */
1333         name = talloc_strdup(ctx, s);
1334         if (!name) {
1335                 return false;
1336         }
1337
1338         servername = strrchr_m(name, '\\' );
1339         if (!servername) {
1340                 servername = name;
1341         } else {
1342                 servername++;
1343         }
1344
1345         /* Optimize for the common case */
1346         if (strequal(servername, lp_netbios_name())) {
1347                 return true;
1348         }
1349
1350         /* Check for an alias */
1351         if (is_myname(servername)) {
1352                 return true;
1353         }
1354
1355         /* Check for loopback */
1356         if (strequal(servername, "127.0.0.1") ||
1357                         strequal(servername, "::1")) {
1358                 return true;
1359         }
1360
1361         if (strequal(servername, "localhost")) {
1362                 return true;
1363         }
1364
1365         /* Maybe it's my dns name */
1366         dnsname = get_mydnsfullname();
1367         if (dnsname && strequal(servername, dnsname)) {
1368                 return true;
1369         }
1370
1371         /* Maybe its an IP address? */
1372         if (is_ipaddress(servername)) {
1373                 return is_my_ipaddr(servername);
1374         }
1375
1376         /* Handle possible CNAME records - convert to an IP addr. list. */
1377         {
1378                 /* Use DNS to resolve the name, check all addresses. */
1379                 struct addrinfo *p = NULL;
1380                 struct addrinfo *res = NULL;
1381
1382                 if (!interpret_string_addr_internal(&res,
1383                                 servername,
1384                                 AI_ADDRCONFIG)) {
1385                         return false;
1386                 }
1387
1388                 for (p = res; p; p = p->ai_next) {
1389                         char addr[INET6_ADDRSTRLEN];
1390                         struct sockaddr_storage ss;
1391
1392                         ZERO_STRUCT(ss);
1393                         memcpy(&ss, p->ai_addr, p->ai_addrlen);
1394                         print_sockaddr(addr,
1395                                         sizeof(addr),
1396                                         &ss);
1397                         if (is_my_ipaddr(addr)) {
1398                                 freeaddrinfo(res);
1399                                 return true;
1400                         }
1401                 }
1402                 freeaddrinfo(res);
1403         }
1404
1405         /* No match */
1406         return false;
1407 }
1408
1409 struct getaddrinfo_state {
1410         const char *node;
1411         const char *service;
1412         const struct addrinfo *hints;
1413         struct addrinfo *res;
1414         int ret;
1415 };
1416
1417 static void getaddrinfo_do(void *private_data);
1418 static void getaddrinfo_done(struct tevent_req *subreq);
1419
1420 struct tevent_req *getaddrinfo_send(TALLOC_CTX *mem_ctx,
1421                                     struct tevent_context *ev,
1422                                     struct fncall_context *ctx,
1423                                     const char *node,
1424                                     const char *service,
1425                                     const struct addrinfo *hints)
1426 {
1427         struct tevent_req *req, *subreq;
1428         struct getaddrinfo_state *state;
1429
1430         req = tevent_req_create(mem_ctx, &state, struct getaddrinfo_state);
1431         if (req == NULL) {
1432                 return NULL;
1433         }
1434
1435         state->node = node;
1436         state->service = service;
1437         state->hints = hints;
1438
1439         subreq = fncall_send(state, ev, ctx, getaddrinfo_do, state);
1440         if (tevent_req_nomem(subreq, req)) {
1441                 return tevent_req_post(req, ev);
1442         }
1443         tevent_req_set_callback(subreq, getaddrinfo_done, req);
1444         return req;
1445 }
1446
1447 static void getaddrinfo_do(void *private_data)
1448 {
1449         struct getaddrinfo_state *state =
1450                 (struct getaddrinfo_state *)private_data;
1451
1452         state->ret = getaddrinfo(state->node, state->service, state->hints,
1453                                  &state->res);
1454 }
1455
1456 static void getaddrinfo_done(struct tevent_req *subreq)
1457 {
1458         struct tevent_req *req = tevent_req_callback_data(
1459                 subreq, struct tevent_req);
1460         int ret, err;
1461
1462         ret = fncall_recv(subreq, &err);
1463         TALLOC_FREE(subreq);
1464         if (ret == -1) {
1465                 tevent_req_error(req, err);
1466                 return;
1467         }
1468         tevent_req_done(req);
1469 }
1470
1471 int getaddrinfo_recv(struct tevent_req *req, struct addrinfo **res)
1472 {
1473         struct getaddrinfo_state *state = tevent_req_data(
1474                 req, struct getaddrinfo_state);
1475         int err;
1476
1477         if (tevent_req_is_unix_error(req, &err)) {
1478                 switch(err) {
1479                 case ENOMEM:
1480                         return EAI_MEMORY;
1481                 default:
1482                         return EAI_FAIL;
1483                 }
1484         }
1485         if (state->ret == 0) {
1486                 *res = state->res;
1487         }
1488         return state->ret;
1489 }
1490
1491 int poll_one_fd(int fd, int events, int timeout, int *revents)
1492 {
1493         struct pollfd *fds;
1494         int ret;
1495         int saved_errno;
1496
1497         fds = talloc_zero_array(talloc_tos(), struct pollfd, 1);
1498         if (fds == NULL) {
1499                 errno = ENOMEM;
1500                 return -1;
1501         }
1502         fds[0].fd = fd;
1503         fds[0].events = events;
1504
1505         ret = poll(fds, 1, timeout);
1506
1507         /*
1508          * Assign whatever poll did, even in the ret<=0 case.
1509          */
1510         *revents = fds[0].revents;
1511         saved_errno = errno;
1512         TALLOC_FREE(fds);
1513         errno = saved_errno;
1514
1515         return ret;
1516 }
1517
1518 int poll_intr_one_fd(int fd, int events, int timeout, int *revents)
1519 {
1520         struct pollfd pfd;
1521         int ret;
1522
1523         pfd.fd = fd;
1524         pfd.events = events;
1525
1526         ret = sys_poll_intr(&pfd, 1, timeout);
1527         if (ret <= 0) {
1528                 *revents = 0;
1529                 return ret;
1530         }
1531         *revents = pfd.revents;
1532         return 1;
1533 }