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