]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bnet.c
ebl fix error message about TCP_KEEPIDLE
[bacula/bacula] / bacula / src / lib / bnet.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation plus additions
11    that are listed in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    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, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Network Utility Routines
30  *
31  *  by Kern Sibbald
32  *
33  * Adapted and enhanced for Bacula, originally written
34  * for inclusion in the Apcupsd package
35  *
36  *   Version $Id$
37  */
38
39
40 #include "bacula.h"
41 #include "jcr.h"
42 #include <netdb.h>
43
44 extern time_t watchdog_time;
45
46 #ifndef   INADDR_NONE
47 #define   INADDR_NONE    -1
48 #endif
49
50 #ifdef HAVE_WIN32
51 #define socketRead(fd, buf, len)  recv(fd, buf, len, 0)
52 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
53 #define socketClose(fd)           closesocket(fd)
54 #else
55 #define socketRead(fd, buf, len)  read(fd, buf, len)
56 #define socketWrite(fd, buf, len) write(fd, buf, len)
57 #define socketClose(fd)           close(fd)
58 #endif
59
60 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
61
62 /*
63  * Read a nbytes from the network.
64  * It is possible that the total bytes require in several
65  * read requests
66  */
67
68 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
69 {
70    int32_t nleft, nread;
71
72 #ifdef HAVE_TLS
73    if (bsock->tls) {
74       /* TLS enabled */
75       return (tls_bsock_readn(bsock, ptr, nbytes));
76    }
77 #endif /* HAVE_TLS */
78
79    nleft = nbytes;
80    while (nleft > 0) {
81       errno = 0;
82       nread = socketRead(bsock->fd, ptr, nleft);
83       if (bsock->timed_out || bsock->terminated) {
84          return nread;
85       }
86       if (nread == -1) {
87          if (errno == EINTR) {
88             continue;
89          }
90          if (errno == EAGAIN) {
91             bmicrosleep(0, 200000);  /* try again in 200ms */
92             continue;
93          }
94       }
95       if (nread <= 0) {
96          return nread;             /* error, or EOF */
97       }
98       nleft -= nread;
99       ptr += nread;
100    }
101    return nbytes - nleft;          /* return >= 0 */
102 }
103
104 /*
105  * Write nbytes to the network.
106  * It may require several writes.
107  */
108
109 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
110 {
111    int32_t nleft, nwritten;
112
113    if (bsock->spool) {
114       nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
115       if (nwritten != nbytes) {
116          berrno be;
117          bsock->b_errno = errno;
118          Qmsg1(bsock->jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
119                be.strerror());
120          Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
121          errno = bsock->b_errno;
122          return -1;
123       }
124       return nbytes;
125    }
126
127 #ifdef HAVE_TLS
128    if (bsock->tls) {
129       /* TLS enabled */
130       return (tls_bsock_writen(bsock, ptr, nbytes));
131    }
132 #endif /* HAVE_TLS */
133
134    nleft = nbytes;
135    while (nleft > 0) {
136       do {
137          errno = 0;
138          nwritten = socketWrite(bsock->fd, ptr, nleft);
139          if (bsock->timed_out || bsock->terminated) {
140             return nwritten;
141          }
142       } while (nwritten == -1 && errno == EINTR);
143       /*
144        * If connection is non-blocking, we will get EAGAIN, so
145        * use select() to keep from consuming all the CPU
146        * and try again.
147        */
148       if (nwritten == -1 && errno == EAGAIN) {
149          fd_set fdset;
150          struct timeval tv;
151
152          FD_ZERO(&fdset);
153          FD_SET((unsigned)bsock->fd, &fdset);
154          tv.tv_sec = 10;
155          tv.tv_usec = 0;
156          select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
157          continue;
158       }
159       if (nwritten <= 0) {
160          return nwritten;          /* error */
161       }
162       nleft -= nwritten;
163       ptr += nwritten;
164    }
165    return nbytes - nleft;
166 }
167
168 /*
169  * Receive a message from the other end. Each message consists of
170  * two packets. The first is a header that contains the size
171  * of the data that follows in the second packet.
172  * Returns number of bytes read (may return zero)
173  * Returns -1 on signal (BNET_SIGNAL)
174  * Returns -2 on hard end of file (BNET_HARDEOF)
175  * Returns -3 on error  (BNET_ERROR)
176  *
177  *  Unfortunately, it is a bit complicated because we have these
178  *    four return types:
179  *    1. Normal data
180  *    2. Signal including end of data stream
181  *    3. Hard end of file
182  *    4. Error
183  *  Using is_bnet_stop() and is_bnet_error() you can figure this all out.
184  */
185 int32_t bnet_recv(BSOCK * bsock)
186 {
187    return bsock->recv();
188 }
189
190
191 /*
192  * Return 1 if there are errors on this bsock or it is closed,
193  *   i.e. stop communicating on this line.
194  */
195 bool is_bnet_stop(BSOCK * bsock)
196 {
197    return bsock->errors || bsock->terminated;
198 }
199
200 /*
201  * Return number of errors on socket
202  */
203 int is_bnet_error(BSOCK * bsock)
204 {
205    errno = bsock->b_errno;
206    return bsock->errors;
207 }
208
209 /*
210  * Call here after error during closing to suppress error
211  *  messages which are due to the other end shutting down too.
212  */
213 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
214 {
215    bsock->suppress_error_msgs = flag;
216 }
217
218 /*
219  * Send a message over the network. The send consists of
220  * two network packets. The first is sends a 32 bit integer containing
221  * the length of the data packet which follows.
222  *
223  * Returns: false on failure
224  *          true  on success
225  */
226 bool bnet_send(BSOCK *bsock)
227 {
228    return bsock->send();
229 }
230
231
232 /*
233  * Establish a TLS connection -- server side
234  *  Returns: true  on success
235  *           false on failure
236  */
237 #ifdef HAVE_TLS
238 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
239 {
240    TLS_CONNECTION *tls;
241    
242    tls = new_tls_connection(ctx, bsock->fd);
243    if (!tls) {
244       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
245       return false;
246    }
247
248    bsock->tls = tls;
249
250    /* Initiate TLS Negotiation */
251    if (!tls_bsock_accept(bsock)) {
252       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
253       goto err;
254    }
255
256    if (verify_list) {
257       if (!tls_postconnect_verify_cn(tls, verify_list)) {
258          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
259                                          " Peer certificate did not match a required commonName\n"),
260                                          bsock->host());
261          goto err;
262       }
263    }
264    return true;
265
266 err:
267    free_tls_connection(tls);
268    bsock->tls = NULL;
269    return false;
270 }
271
272 /*
273  * Establish a TLS connection -- client side
274  * Returns: true  on success
275  *          false on failure
276  */
277 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
278 {
279    TLS_CONNECTION *tls;
280
281    tls  = new_tls_connection(ctx, bsock->fd);
282    if (!tls) {
283       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
284       return false;
285    }
286
287    bsock->tls = tls;
288
289    /* Initiate TLS Negotiation */
290    if (!tls_bsock_connect(bsock)) {
291       goto err;
292    }
293
294    /* If there's an Allowed CN verify list, use that to validate the remote
295     * certificate's CN. Otherwise, we use standard host/CN matching. */
296    if (verify_list) {
297       if (!tls_postconnect_verify_cn(tls, verify_list)) {
298          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
299                                          " Peer certificate did not match a required commonName\n"),
300                                          bsock->host());
301          goto err;
302       }
303    } else {
304       if (!tls_postconnect_verify_host(tls, bsock->host())) {
305          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), 
306                bsock->host());
307          goto err;
308       }
309    }
310
311    return true;
312
313 err:
314    free_tls_connection(tls);
315    bsock->tls = NULL;
316    return false;
317 }
318 #else
319
320 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
321 {
322    Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
323    return false;
324 }
325
326 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
327 {
328    Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
329    return false;
330 }
331
332 #endif /* HAVE_TLS */
333
334 /*
335  * Wait for a specified time for data to appear on
336  * the BSOCK connection.
337  *
338  *   Returns: 1 if data available
339  *            0 if timeout
340  *           -1 if error
341  */
342 int bnet_wait_data(BSOCK * bsock, int sec)
343 {
344    fd_set fdset;
345    struct timeval tv;
346
347    FD_ZERO(&fdset);
348    FD_SET((unsigned)bsock->fd, &fdset);
349    for (;;) {
350       tv.tv_sec = sec;
351       tv.tv_usec = 0;
352       switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
353       case 0:                      /* timeout */
354          bsock->b_errno = 0;
355          return 0;
356       case -1:
357          bsock->b_errno = errno;
358          if (errno == EINTR) {
359             continue;
360          }
361          return -1;                /* error return */
362       default:
363          bsock->b_errno = 0;
364          return 1;
365       }
366    }
367 }
368
369 /*
370  * As above, but returns on interrupt
371  */
372 int bnet_wait_data_intr(BSOCK * bsock, int sec)
373 {
374    fd_set fdset;
375    struct timeval tv;
376
377    FD_ZERO(&fdset);
378    FD_SET((unsigned)bsock->fd, &fdset);
379    tv.tv_sec = sec;
380    tv.tv_usec = 0;
381    switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
382    case 0:                      /* timeout */
383       bsock->b_errno = 0;
384       return 0;
385    case -1:
386       bsock->b_errno = errno;
387       return -1;                /* error return */
388    default:
389       bsock->b_errno = 0;
390    }
391    return 1;
392 }
393
394 #ifndef NETDB_INTERNAL
395 #define NETDB_INTERNAL  -1         /* See errno. */
396 #endif
397 #ifndef NETDB_SUCCESS
398 #define NETDB_SUCCESS   0          /* No problem. */
399 #endif
400 #ifndef HOST_NOT_FOUND
401 #define HOST_NOT_FOUND  1          /* Authoritative Answer Host not found. */
402 #endif
403 #ifndef TRY_AGAIN
404 #define TRY_AGAIN       2          /* Non-Authoritative Host not found, or SERVERFAIL. */
405 #endif
406 #ifndef NO_RECOVERY
407 #define NO_RECOVERY     3          /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
408 #endif
409 #ifndef NO_DATA
410 #define NO_DATA         4          /* Valid name, no data record of requested type. */
411 #endif
412
413 /*
414  * Get human readable error for gethostbyname()
415  */
416 static const char *gethost_strerror()
417 {
418    const char *msg;
419    berrno be;
420    switch (h_errno) {
421    case NETDB_INTERNAL:
422       msg = be.strerror();
423       break;
424    case NETDB_SUCCESS:
425       msg = _("No problem.");
426       break;
427    case HOST_NOT_FOUND:
428       msg = _("Authoritative answer for host not found.");
429       break;
430    case TRY_AGAIN:
431       msg = _("Non-authoritative for host not found, or ServerFail.");
432       break;
433    case NO_RECOVERY:
434       msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
435       break;
436    case NO_DATA:
437       msg = _("Valid name, no data record of resquested type.");
438       break;
439    default:
440       msg = _("Unknown error.");
441    }
442    return msg;
443 }
444
445
446
447
448 static IPADDR *add_any(int family)
449 {
450    IPADDR *addr = New(IPADDR(family));
451    addr->set_type(IPADDR::R_MULTIPLE);
452    addr->set_addr_any();
453    return addr;
454 }
455
456 static const char *resolv_host(int family, const char *host, dlist * addr_list)
457 {
458    struct hostent *hp;
459    const char *errmsg;
460
461    P(ip_mutex);                       /* gethostbyname() is not thread safe */
462 #ifdef HAVE_GETHOSTBYNAME2
463    if ((hp = gethostbyname2(host, family)) == NULL) {
464 #else
465    if ((hp = gethostbyname(host)) == NULL) {
466 #endif
467       /* may be the strerror give not the right result -:( */
468       errmsg = gethost_strerror();
469       V(ip_mutex);
470       return errmsg;
471    } else {
472       char **p;
473       for (p = hp->h_addr_list; *p != 0; p++) {
474          IPADDR *addr =  New(IPADDR(hp->h_addrtype));
475          addr->set_type(IPADDR::R_MULTIPLE);
476          if (addr->get_family() == AF_INET) {
477              addr->set_addr4((struct in_addr*)*p);
478          }
479 #ifdef HAVE_IPV6
480          else {
481              addr->set_addr6((struct in6_addr*)*p);
482          }
483 #endif
484          addr_list->append(addr);
485       }
486       V(ip_mutex);
487    }
488    return NULL;
489 }
490
491 /*
492  * i host = 0 mean INADDR_ANY only ipv4
493  */
494 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
495 {
496    struct in_addr inaddr;
497    IPADDR *addr = 0;
498    const char *errmsg;
499 #ifdef HAVE_IPV6
500    struct in6_addr inaddr6;
501 #endif
502
503    dlist *addr_list = New(dlist(addr, &addr->link));
504    if (!host || host[0] == '\0') {
505       if (family != 0) {
506          addr_list->append(add_any(family));
507       } else {
508          addr_list->append(add_any(AF_INET));
509 #ifdef HAVE_IPV6
510          addr_list->append(add_any(AF_INET6));
511 #endif
512       }
513    } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
514       addr = New(IPADDR(AF_INET));
515       addr->set_type(IPADDR::R_MULTIPLE);
516       addr->set_addr4(&inaddr);
517       addr_list->append(addr);
518    } else
519 #ifdef HAVE_IPV6
520    if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
521       addr = New(IPADDR(AF_INET6));
522       addr->set_type(IPADDR::R_MULTIPLE);
523       addr->set_addr6(&inaddr6);
524       addr_list->append(addr);
525    } else
526 #endif
527    {
528       if (family != 0) {
529          errmsg = resolv_host(family, host, addr_list);
530          if (errmsg) {
531             *errstr = errmsg;
532             free_addresses(addr_list);
533             return 0;
534          }
535       } else {
536          errmsg = resolv_host(AF_INET, host, addr_list);
537 #ifdef HAVE_IPV6
538          if (errmsg) {
539             errmsg = resolv_host(AF_INET6, host, addr_list);
540          }
541 #endif
542          if (errmsg) {
543             *errstr = errmsg;
544             free_addresses(addr_list);
545             return 0;
546          }
547       }
548    }
549    return addr_list;
550 }
551
552 /*
553  * Open a TCP connection to the UPS network server
554  * Returns NULL
555  * Returns BSOCK * pointer on success
556  *
557  */
558 static BSOCK *bnet_open(JCR *jcr, const char *name, char *host, char *service,
559                         int port, utime_t heart_beat, int *fatal)
560 {
561    int sockfd = -1;
562    dlist *addr_list;
563    IPADDR *ipaddr;
564    bool connected = false;
565    int turnon = 1;
566    const char *errstr;
567    int save_errno = 0;
568
569    /*
570     * Fill in the structure serv_addr with the address of
571     * the server that we want to connect with.
572     */
573    if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
574       /* Note errstr is not malloc'ed */
575       Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
576             host, errstr);
577       Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
578             host, errstr);
579       *fatal = 1;
580       return NULL;
581    }
582
583    foreach_dlist(ipaddr, addr_list) {
584       ipaddr->set_port_net(htons(port));
585       char allbuf[256 * 10];
586       char curbuf[256];
587       Dmsg2(100, "Current %sAll %s\n",
588                    ipaddr->build_address_str(curbuf, sizeof(curbuf)),
589                    build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
590       /* Open a TCP socket */
591       if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
592          berrno be;
593          save_errno = errno;
594          *fatal = 1;
595          Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
596             ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
597          continue;
598       }
599       /*
600        * Keep socket from timing out from inactivity
601        */
602       if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
603          berrno be;
604          Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
605                be.strerror());
606       }
607 #if defined(TCP_KEEPIDLE)
608       if (heart_beat) {
609          int opt = heart_beat
610          if (setsockopt(sockfd, IPPROTO_IP, TCP_KEEPIDLE, (sockopt_val_t)&opt, sizeof(opt)) < 0) {
611             berrno be;
612             Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPIDLE on socket: %s\n"),
613                   be.strerror());
614          }
615       }
616 #endif
617
618       /* connect to server */
619       if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
620          save_errno = errno;
621          socketClose(sockfd);
622          continue;
623       }
624       *fatal = 0;
625       connected = true;
626       break;
627    }
628
629    if (!connected) {
630       free_addresses(addr_list);
631       errno = save_errno;
632       return NULL;
633    }
634    /*
635     * Keep socket from timing out from inactivity
636     *   Do this a second time out of paranoia
637     */
638    if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
639       berrno be;
640       Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
641             be.strerror());
642    }
643    BSOCK* ret =  init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
644    free_addresses(addr_list);
645    return ret;
646 }
647
648 /*
649  * Try to connect to host for max_retry_time at retry_time intervals.
650  */
651 BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
652                     utime_t heart_beat,
653                     const char *name, char *host, char *service, int port,
654                     int verbose)
655 {
656    int i;
657    BSOCK *bsock;
658    int fatal = 0;
659    time_t begin_time = time(NULL);
660    time_t now;
661
662    for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, heart_beat, &fatal)) == NULL;
663         i -= retry_interval) {
664       berrno be;
665       if (fatal || (jcr && job_canceled(jcr))) {
666          return NULL;
667       }
668       Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
669             name, host, port, be.strerror());
670       if (i < 0) {
671          i = 60 * 5;               /* complain again in 5 minutes */
672          if (verbose)
673             Qmsg4(jcr, M_WARNING, 0, _(
674                "Could not connect to %s on %s:%d. ERR=%s\n"
675                "Retrying ...\n"), name, host, port, be.strerror());
676       }
677       bmicrosleep(retry_interval, 0);
678       now = time(NULL);
679       if (begin_time + max_retry_time <= now) {
680          Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
681                name, host, port, be.strerror());
682          return NULL;
683       }
684    }
685    return bsock;
686 }
687
688
689 /*
690  * Return the string for the error that occurred
691  * on the socket. Only the first error is retained.
692  */
693 const char *bnet_strerror(BSOCK * bsock)
694 {
695    berrno be;
696    if (bsock->errmsg == NULL) {
697       bsock->errmsg = get_pool_memory(PM_MESSAGE);
698    }
699    pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
700    return bsock->errmsg;
701 }
702
703 /*
704  * Format and send a message
705  *  Returns: false on error
706  *           true  on success
707  */
708 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
709 {
710    va_list arg_ptr;
711    int maxlen;
712
713    if (bs->errors || bs->terminated) {
714       return false;
715    }
716    /* This probably won't work, but we vsnprintf, then if we
717     * get a negative length or a length greater than our buffer
718     * (depending on which library is used), the printf was truncated, so
719     * get a bigger buffer and try again.
720     */
721    for (;;) {
722       maxlen = sizeof_pool_memory(bs->msg) - 1;
723       va_start(arg_ptr, fmt);
724       bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
725       va_end(arg_ptr);
726       if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
727          break;
728       }
729       bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
730    }
731    return bs->send();
732 // return bnet_send(bs);
733 }
734
735 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
736 #if !defined(HAVE_WIN32)
737     if (bs->peer_addr.sin_family == 0) {
738         socklen_t salen = sizeof(bs->peer_addr);
739         int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
740         if (rval < 0) return rval;
741     }
742     if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
743         return -1;
744
745     return 0;
746 #else
747     return -1;
748 #endif
749 }
750 /*
751  * Set the network buffer size, suggested size is in size.
752  *  Actual size obtained is returned in bs->msglen
753  *
754  *  Returns: 0 on failure
755  *           1 on success
756  */
757 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
758 {
759    uint32_t dbuf_size, start_size;
760 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
761    int opt;
762    opt = IPTOS_THROUGHPUT;
763    setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
764 #endif
765
766    if (size != 0) {
767       dbuf_size = size;
768    } else {
769       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
770    }
771    start_size = dbuf_size;
772    if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
773       Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
774       return false;
775    }
776    if (rw & BNET_SETBUF_READ) {
777       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
778               SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
779          berrno be;
780          Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
781          dbuf_size -= TAPE_BSIZE;
782       }
783       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
784       if (dbuf_size != start_size) {
785          Qmsg1(bs->jcr(), M_WARNING, 0,
786                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
787       }
788       if (dbuf_size % TAPE_BSIZE != 0) {
789          Qmsg1(bs->jcr(), M_ABORT, 0,
790                _("Network buffer size %d not multiple of tape block size.\n"),
791                dbuf_size);
792       }
793    }
794    if (size != 0) {
795       dbuf_size = size;
796    } else {
797       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
798    }
799    start_size = dbuf_size;
800    if (rw & BNET_SETBUF_WRITE) {
801       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
802               SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
803          berrno be;
804          Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
805          dbuf_size -= TAPE_BSIZE;
806       }
807       Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
808       if (dbuf_size != start_size) {
809          Qmsg1(bs->jcr(), M_WARNING, 0,
810                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
811       }
812       if (dbuf_size % TAPE_BSIZE != 0) {
813          Qmsg1(bs->jcr(), M_ABORT, 0,
814                _("Network buffer size %d not multiple of tape block size.\n"),
815                dbuf_size);
816       }
817    }
818
819    bs->msglen = dbuf_size;
820    return true;
821 }
822
823 /*
824  * Set socket non-blocking
825  * Returns previous socket flag
826  */
827 int bnet_set_nonblocking (BSOCK *bsock) {
828 #ifndef HAVE_WIN32
829    int oflags;
830
831    /* Get current flags */
832    if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
833       berrno be;
834       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
835    }
836
837    /* Set O_NONBLOCK flag */
838    if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
839       berrno be;
840       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
841    }
842
843    bsock->blocking = 0;
844    return oflags;
845 #else
846    int flags;
847    u_long ioctlArg = 1;
848
849    flags = bsock->blocking;
850    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
851    bsock->blocking = 0;
852
853    return flags;
854 #endif
855 }
856
857 /*
858  * Set socket blocking
859  * Returns previous socket flags
860  */
861 int bnet_set_blocking (BSOCK *bsock) 
862 {
863 #ifndef HAVE_WIN32
864    int oflags;
865    /* Get current flags */
866    if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
867       berrno be;
868       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
869    }
870
871    /* Set O_NONBLOCK flag */
872    if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
873       berrno be;
874       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
875    }
876
877    bsock->blocking = 1;
878    return oflags;
879 #else
880    int flags;
881    u_long ioctlArg = 0;
882
883    flags = bsock->blocking;
884    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
885    bsock->blocking = 1;
886
887    return flags;
888 #endif
889 }
890
891 /*
892  * Restores socket flags
893  */
894 void bnet_restore_blocking (BSOCK *bsock, int flags) 
895 {
896 #ifndef HAVE_WIN32
897    if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
898       berrno be;
899       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
900    }
901
902    bsock->blocking = (flags & O_NONBLOCK);
903 #else
904    u_long ioctlArg = flags;
905
906    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
907    bsock->blocking = 1;
908 #endif
909 }
910
911
912 /*
913  * Send a network "signal" to the other end
914  *  This consists of sending a negative packet length
915  *
916  *  Returns: false on failure
917  *           true  on success
918  */
919 bool bnet_sig(BSOCK * bs, int signal)
920 {
921    return bs->signal(signal);
922 }
923
924 /*
925  * Convert a network "signal" code into
926  * human readable ASCII.
927  */
928 const char *bnet_sig_to_ascii(BSOCK * bs)
929 {
930    static char buf[30];
931    switch (bs->msglen) {
932    case BNET_EOD:
933       return "BNET_EOD";           /* end of data stream */
934    case BNET_EOD_POLL:
935       return "BNET_EOD_POLL";
936    case BNET_STATUS:
937       return "BNET_STATUS";
938    case BNET_TERMINATE:
939       return "BNET_TERMINATE";     /* terminate connection */
940    case BNET_POLL:
941       return "BNET_POLL";
942    case BNET_HEARTBEAT:
943       return "BNET_HEARTBEAT";
944    case BNET_HB_RESPONSE:
945       return "BNET_HB_RESPONSE";
946    case BNET_PROMPT:
947       return "BNET_PROMPT";
948    default:
949       sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
950       return buf;
951    }
952 }
953
954
955 /* Initialize internal socket structure.
956  *  This probably should be done in net_open
957  */
958 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
959                   struct sockaddr *client_addr)
960 {
961    Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
962    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
963    memset(bsock, 0, sizeof(BSOCK));
964    bsock->fd = sockfd;
965    bsock->tls = NULL;
966    bsock->errors = 0;
967    bsock->blocking = 1;
968    bsock->msg = get_pool_memory(PM_MESSAGE);
969    bsock->errmsg = get_pool_memory(PM_MESSAGE);
970    bsock->set_who(bstrdup(who));
971    bsock->set_host(bstrdup(host));
972    bsock->set_port(port);
973    memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
974    memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
975    /*
976     * ****FIXME**** reduce this to a few hours once
977     *   heartbeats are implemented
978     */
979    bsock->timeout = 60 * 60 * 6 * 24;   /* 6 days timeout */
980    bsock->set_jcr(jcr);
981    return bsock;
982 }
983
984 BSOCK *dup_bsock(BSOCK * osock)
985 {
986    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
987    memcpy(bsock, osock, sizeof(BSOCK));
988    bsock->msg = get_pool_memory(PM_MESSAGE);
989    bsock->errmsg = get_pool_memory(PM_MESSAGE);
990    if (osock->who()) {
991       bsock->set_who(bstrdup(osock->who()));
992    }
993    if (osock->host()) {
994       bsock->set_host(bstrdup(osock->host()));
995    }
996    bsock->duped = true;
997    return bsock;
998 }
999
1000 /* Close the network connection */
1001 void bnet_close(BSOCK * bsock)
1002 {
1003    bsock->close();                    /* this calls destroy */
1004 }
1005
1006 void term_bsock(BSOCK * bsock)
1007 {
1008    bsock->destroy();
1009 }