]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bnet.c
43b71c8136b0c2f837761aa387e96d81bead914a
[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 | b_errno_win32;
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    btimer_t *tid = NULL;
662
663    /* Try to trap out of OS call when time expires */
664    tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time);
665    
666    for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, heart_beat, &fatal)) == NULL;
667         i -= retry_interval) {
668       berrno be;
669       if (fatal || (jcr && job_canceled(jcr))) {
670          bsock = NULL;
671          goto bail_out;
672       }
673       Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
674             name, host, port, be.strerror());
675       if (i < 0) {
676          i = 60 * 5;               /* complain again in 5 minutes */
677          if (verbose)
678             Qmsg4(jcr, M_WARNING, 0, _(
679                "Could not connect to %s on %s:%d. ERR=%s\n"
680                "Retrying ...\n"), name, host, port, be.strerror());
681       }
682       bmicrosleep(retry_interval, 0);
683       now = time(NULL);
684       if (begin_time + max_retry_time <= now) {
685          Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
686                name, host, port, be.strerror());
687          bsock = NULL;
688          goto bail_out;
689       }
690    }
691
692 bail_out:
693    if (tid) {
694       stop_thread_timer(tid);
695    }
696    return bsock;
697 }
698
699
700 /*
701  * Return the string for the error that occurred
702  * on the socket. Only the first error is retained.
703  */
704 const char *bnet_strerror(BSOCK * bsock)
705 {
706    berrno be;
707    if (bsock->errmsg == NULL) {
708       bsock->errmsg = get_pool_memory(PM_MESSAGE);
709    }
710    pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
711    return bsock->errmsg;
712 }
713
714 /*
715  * Format and send a message
716  *  Returns: false on error
717  *           true  on success
718  */
719 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
720 {
721    va_list arg_ptr;
722    int maxlen;
723
724    if (bs->errors || bs->terminated) {
725       return false;
726    }
727    /* This probably won't work, but we vsnprintf, then if we
728     * get a negative length or a length greater than our buffer
729     * (depending on which library is used), the printf was truncated, so
730     * get a bigger buffer and try again.
731     */
732    for (;;) {
733       maxlen = sizeof_pool_memory(bs->msg) - 1;
734       va_start(arg_ptr, fmt);
735       bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
736       va_end(arg_ptr);
737       if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
738          break;
739       }
740       bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
741    }
742    return bs->send();
743 }
744
745 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) 
746 {
747 #if !defined(HAVE_WIN32)
748     if (bs->peer_addr.sin_family == 0) {
749         socklen_t salen = sizeof(bs->peer_addr);
750         int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
751         if (rval < 0) return rval;
752     }
753     if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
754         return -1;
755
756     return 0;
757 #else
758     return -1;
759 #endif
760 }
761 /*
762  * Set the network buffer size, suggested size is in size.
763  *  Actual size obtained is returned in bs->msglen
764  *
765  *  Returns: 0 on failure
766  *           1 on success
767  */
768 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
769 {
770    uint32_t dbuf_size, start_size;
771 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
772    int opt;
773    opt = IPTOS_THROUGHPUT;
774    setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
775 #endif
776
777    if (size != 0) {
778       dbuf_size = size;
779    } else {
780       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
781    }
782    start_size = dbuf_size;
783    if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
784       Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
785       return false;
786    }
787    if (rw & BNET_SETBUF_READ) {
788       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
789               SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
790          berrno be;
791          Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
792          dbuf_size -= TAPE_BSIZE;
793       }
794       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
795       if (dbuf_size != start_size) {
796          Qmsg1(bs->jcr(), M_WARNING, 0,
797                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
798       }
799       if (dbuf_size % TAPE_BSIZE != 0) {
800          Qmsg1(bs->jcr(), M_ABORT, 0,
801                _("Network buffer size %d not multiple of tape block size.\n"),
802                dbuf_size);
803       }
804    }
805    if (size != 0) {
806       dbuf_size = size;
807    } else {
808       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
809    }
810    start_size = dbuf_size;
811    if (rw & BNET_SETBUF_WRITE) {
812       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
813               SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
814          berrno be;
815          Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
816          dbuf_size -= TAPE_BSIZE;
817       }
818       Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
819       if (dbuf_size != start_size) {
820          Qmsg1(bs->jcr(), M_WARNING, 0,
821                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
822       }
823       if (dbuf_size % TAPE_BSIZE != 0) {
824          Qmsg1(bs->jcr(), M_ABORT, 0,
825                _("Network buffer size %d not multiple of tape block size.\n"),
826                dbuf_size);
827       }
828    }
829
830    bs->msglen = dbuf_size;
831    return true;
832 }
833
834 /*
835  * Set socket non-blocking
836  * Returns previous socket flag
837  */
838 int bnet_set_nonblocking (BSOCK *bsock) {
839 #ifndef HAVE_WIN32
840    int oflags;
841
842    /* Get current flags */
843    if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
844       berrno be;
845       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
846    }
847
848    /* Set O_NONBLOCK flag */
849    if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
850       berrno be;
851       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
852    }
853
854    bsock->blocking = 0;
855    return oflags;
856 #else
857    int flags;
858    u_long ioctlArg = 1;
859
860    flags = bsock->blocking;
861    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
862    bsock->blocking = 0;
863
864    return flags;
865 #endif
866 }
867
868 /*
869  * Set socket blocking
870  * Returns previous socket flags
871  */
872 int bnet_set_blocking (BSOCK *bsock) 
873 {
874 #ifndef HAVE_WIN32
875    int oflags;
876    /* Get current flags */
877    if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
878       berrno be;
879       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
880    }
881
882    /* Set O_NONBLOCK flag */
883    if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
884       berrno be;
885       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
886    }
887
888    bsock->blocking = 1;
889    return oflags;
890 #else
891    int flags;
892    u_long ioctlArg = 0;
893
894    flags = bsock->blocking;
895    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
896    bsock->blocking = 1;
897
898    return flags;
899 #endif
900 }
901
902 /*
903  * Restores socket flags
904  */
905 void bnet_restore_blocking (BSOCK *bsock, int flags) 
906 {
907 #ifndef HAVE_WIN32
908    if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
909       berrno be;
910       Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
911    }
912
913    bsock->blocking = (flags & O_NONBLOCK);
914 #else
915    u_long ioctlArg = flags;
916
917    ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
918    bsock->blocking = 1;
919 #endif
920 }
921
922
923 /*
924  * Send a network "signal" to the other end
925  *  This consists of sending a negative packet length
926  *
927  *  Returns: false on failure
928  *           true  on success
929  */
930 bool bnet_sig(BSOCK * bs, int signal)
931 {
932    return bs->signal(signal);
933 }
934
935 /*
936  * Convert a network "signal" code into
937  * human readable ASCII.
938  */
939 const char *bnet_sig_to_ascii(BSOCK * bs)
940 {
941    static char buf[30];
942    switch (bs->msglen) {
943    case BNET_EOD:
944       return "BNET_EOD";           /* end of data stream */
945    case BNET_EOD_POLL:
946       return "BNET_EOD_POLL";
947    case BNET_STATUS:
948       return "BNET_STATUS";
949    case BNET_TERMINATE:
950       return "BNET_TERMINATE";     /* terminate connection */
951    case BNET_POLL:
952       return "BNET_POLL";
953    case BNET_HEARTBEAT:
954       return "BNET_HEARTBEAT";
955    case BNET_HB_RESPONSE:
956       return "BNET_HB_RESPONSE";
957    case BNET_PROMPT:
958       return "BNET_PROMPT";
959    default:
960       sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
961       return buf;
962    }
963 }
964
965
966 /* Initialize internal socket structure.
967  *  This probably should be done in net_open
968  */
969 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
970                   struct sockaddr *client_addr)
971 {
972    Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
973    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
974    memset(bsock, 0, sizeof(BSOCK));
975    bsock->fd = sockfd;
976    bsock->tls = NULL;
977    bsock->errors = 0;
978    bsock->blocking = 1;
979    bsock->msg = get_pool_memory(PM_MESSAGE);
980    bsock->errmsg = get_pool_memory(PM_MESSAGE);
981    bsock->set_who(bstrdup(who));
982    bsock->set_host(bstrdup(host));
983    bsock->set_port(port);
984    memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
985    memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
986    /*
987     * ****FIXME**** reduce this to a few hours once
988     *   heartbeats are implemented
989     */
990    bsock->timeout = 60 * 60 * 6 * 24;   /* 6 days timeout */
991    bsock->set_jcr(jcr);
992    return bsock;
993 }
994
995 BSOCK *dup_bsock(BSOCK * osock)
996 {
997    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
998    memcpy(bsock, osock, sizeof(BSOCK));
999    bsock->msg = get_pool_memory(PM_MESSAGE);
1000    bsock->errmsg = get_pool_memory(PM_MESSAGE);
1001    if (osock->who()) {
1002       bsock->set_who(bstrdup(osock->who()));
1003    }
1004    if (osock->host()) {
1005       bsock->set_host(bstrdup(osock->host()));
1006    }
1007    bsock->duped = true;
1008    return bsock;
1009 }
1010
1011 /* Close the network connection */
1012 void bnet_close(BSOCK * bsock)
1013 {
1014    bsock->close();                    /* this calls destroy */
1015 }
1016
1017 void term_bsock(BSOCK * bsock)
1018 {
1019    bsock->destroy();
1020 }