]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bnet.c
This commit was manufactured by cvs2svn to create tag
[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 len 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             Qmsg5(bsock->jcr, M_ERROR, 0,
404                   _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), 
405                   bsock->msglen, bsock->who,
406                   bsock->host, bsock->port, bnet_strerror(bsock));
407          }
408       } else {
409          Qmsg5(bsock->jcr, M_ERROR, 0,
410                _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
411                bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
412       }
413       return false;
414    }
415    return true;
416 }
417
418 /*
419  * Establish an SSL connection -- server side
420  *  Codes that ssl_need and ssl_has can take
421  *    BNET_SSL_NONE      I cannot do ssl
422  *    BNET_SSL_OK        I can do ssl, but it is not required on my end
423  *    BNET_SSL_REQUIRED  ssl is required on my end
424  */
425 int bnet_ssl_server(BSOCK * bsock, char *password, int ssl_need, int ssl_has)
426 {
427    /* Check to see if what we need (ssl_need) corresponds to what he has (ssl_has) */
428    /* The other side expects a response from us */
429    return 1;
430 }
431
432 /*
433  * Establish an SSL connection -- client side
434  */
435 int bnet_ssl_client(BSOCK * bsock, char *password, int ssl_need)
436 {
437    /* We are the client so we must wait for the server to notify us */
438    return 1;
439 }
440
441
442 /*
443  * Wait for a specified time for data to appear on
444  * the BSOCK connection.
445  *
446  *   Returns: 1 if data available
447  *            0 if timeout
448  *           -1 if error
449  */
450 int bnet_wait_data(BSOCK * bsock, int sec)
451 {
452    fd_set fdset;
453    struct timeval tv;
454
455    FD_ZERO(&fdset);
456    FD_SET((unsigned)bsock->fd, &fdset);
457    tv.tv_sec = sec;
458    tv.tv_usec = 0;
459    for (;;) {
460       switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
461       case 0:                      /* timeout */
462          bsock->b_errno = 0;
463          return 0;
464       case -1:
465          bsock->b_errno = errno;
466          if (errno == EINTR || errno == EAGAIN) {
467             continue;
468          }
469          return -1;                /* error return */
470       default:
471          bsock->b_errno = 0;
472          return 1;
473       }
474    }
475 }
476
477 /*
478  * As above, but returns on interrupt
479  */
480 int bnet_wait_data_intr(BSOCK * bsock, int sec)
481 {
482    fd_set fdset;
483    struct timeval tv;
484
485    FD_ZERO(&fdset);
486    FD_SET((unsigned)bsock->fd, &fdset);
487    tv.tv_sec = sec;
488    tv.tv_usec = 0;
489    for (;;) {
490       switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
491       case 0:                      /* timeout */
492          bsock->b_errno = 0;
493          return 0;
494       case -1:
495          bsock->b_errno = errno;
496          return -1;                /* error return */
497       default:
498          bsock->b_errno = 0;
499          return 1;
500       }
501    }
502 }
503
504 #ifndef NETDB_INTERNAL
505 #define NETDB_INTERNAL  -1         /* See errno. */
506 #endif
507 #ifndef NETDB_SUCCESS
508 #define NETDB_SUCCESS   0          /* No problem. */
509 #endif
510 #ifndef HOST_NOT_FOUND
511 #define HOST_NOT_FOUND  1          /* Authoritative Answer Host not found. */
512 #endif
513 #ifndef TRY_AGAIN
514 #define TRY_AGAIN       2          /* Non-Authoritative Host not found, or SERVERFAIL. */
515 #endif
516 #ifndef NO_RECOVERY
517 #define NO_RECOVERY     3          /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
518 #endif
519 #ifndef NO_DATA
520 #define NO_DATA         4          /* Valid name, no data record of requested type. */
521 #endif
522
523 /*
524  * Get human readable error for gethostbyname()
525  */
526 static const char *gethost_strerror()
527 {
528    const char *msg;
529    switch (h_errno) {
530    case NETDB_INTERNAL:
531       msg = strerror(errno);
532       break;
533    case NETDB_SUCCESS:
534       msg = "No problem.";
535       break;
536    case HOST_NOT_FOUND:
537       msg = "Authoritative answer for host not found.";
538       break;
539    case TRY_AGAIN:
540       msg = "Non-authoritative for host not found, or ServerFail.";
541       break;
542    case NO_RECOVERY:
543       msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
544       break;
545    case NO_DATA:
546       msg = "Valid name, no data record of resquested type.";
547       break;
548    default:
549       msg = "Unknown error.";
550    }
551    return msg;
552 }
553
554
555
556
557 static IPADDR *add_any(int family)
558 {
559    IPADDR *addr = New(IPADDR(family));
560    addr->set_type(IPADDR::R_MULTIPLE);
561    addr->set_addr_any();
562    return addr;
563 }
564
565 static const char *resolv_host(int family, const char *host, dlist * addr_list)
566 {
567    struct hostent *hp;
568    const char *errmsg;
569
570    P(ip_mutex);
571 #ifdef HAVE_GETHOSTBYNAME2
572    if ((hp = gethostbyname2(host, family)) == NULL) {
573 #else
574    if ((hp = gethostbyname(host)) == NULL) {
575 #endif
576       /* may be the strerror give not the right result -:( */
577       errmsg = gethost_strerror();
578       V(ip_mutex);
579       return errmsg;
580    } else {
581       char **p;
582       for (p = hp->h_addr_list; *p != 0; p++) {
583          IPADDR *addr =  New(IPADDR(hp->h_addrtype));
584          addr->set_type(IPADDR::R_MULTIPLE);
585          if (addr->get_family() == AF_INET) {
586              addr->set_addr4((struct in_addr*)*p);
587          }
588 #ifdef HAVE_IPV6
589          else {
590              addr->set_addr6((struct in6_addr*)*p);
591          }
592 #endif
593          addr_list->append(addr);
594       }
595       V(ip_mutex);
596    }
597    return NULL;
598 }
599
600 /*
601  * i host = 0 mean INADDR_ANY only ipv4
602  */
603 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
604 {
605    struct in_addr inaddr;
606    IPADDR *addr = 0;
607    const char *errmsg;
608 #ifdef HAVE_IPV6
609    struct in6_addr inaddr6;
610 #endif
611
612    dlist *addr_list = New(dlist(addr, &addr->link));
613    if (!host || host[0] == '\0') {
614       if (family != 0) {
615          addr_list->append(add_any(family));
616       } else {
617          addr_list->append(add_any(AF_INET));
618 #ifdef HAVE_IPV6
619          addr_list->append(add_any(AF_INET6));
620 #endif
621       }
622    } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
623       addr = New(IPADDR(AF_INET));
624       addr->set_type(IPADDR::R_MULTIPLE);
625       addr->set_addr4(&inaddr);
626       addr_list->append(addr);
627    } else
628 #ifdef HAVE_IPV6
629    if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
630       addr = New(IPADDR(AF_INET6));
631       addr->set_type(IPADDR::R_MULTIPLE);
632       addr->set_addr6(&inaddr6);
633       addr_list->append(addr);
634    } else
635 #endif
636    {
637       if (family != 0) {
638          errmsg = resolv_host(family, host, addr_list);
639          if (errmsg) {
640             *errstr = errmsg;
641             free_addresses(addr_list);
642             return 0;
643          }
644       } else {
645          errmsg = resolv_host(AF_INET, host, addr_list);
646 #ifdef HAVE_IPV6
647          if (errmsg) {
648             errmsg = resolv_host(AF_INET6, host, addr_list);
649          }
650 #endif
651          if (errmsg) {
652             *errstr = errmsg;
653             free_addresses(addr_list);
654             return 0;
655          }
656       }
657    }
658    return addr_list;
659 }
660
661 /*
662  * Open a TCP connection to the UPS network server
663  * Returns NULL
664  * Returns BSOCK * pointer on success
665  *
666  */
667 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
668                         int port, int *fatal)
669 {
670    int sockfd = -1;
671    dlist *addr_list;
672    IPADDR *ipaddr;
673    bool connected = false;
674    int turnon = 1;
675    const char *errstr;
676    int save_errno = 0;
677
678    /*
679     * Fill in the structure serv_addr with the address of
680     * the server that we want to connect with.
681     */
682    if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
683       /* Note errstr is not malloc'ed */
684       Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
685             host, errstr);
686       Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
687             host, errstr);
688       *fatal = 1;
689       return NULL;
690    }
691
692    foreach_dlist(ipaddr, addr_list) {
693       ipaddr->set_port_net(htons(port));
694       char allbuf[256 * 10];
695       char curbuf[256];
696       Dmsg2(100, "Current %sAll %s\n",
697                    ipaddr->build_address_str(curbuf, sizeof(curbuf)),
698                    build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
699       /* Open a TCP socket */
700       if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
701          berrno be;
702          save_errno = errno;
703          *fatal = 1;
704          Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
705             ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
706          continue;
707       }
708       /*
709        * Keep socket from timing out from inactivity
710        */
711       if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
712          berrno be;
713          Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
714                be.strerror());
715       }
716       /* connect to server */
717       if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
718          save_errno = errno;
719          close(sockfd);
720          continue;
721       }
722       *fatal = 0;
723       connected = true;
724       break;
725    }
726
727    if (!connected) {
728          free_addresses(addr_list);
729       errno = save_errno;
730       return NULL;
731    }
732    /*
733     * Keep socket from timing out from inactivity
734     *   Do this a second time out of paranoia
735     */
736    if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
737       berrno be;
738       Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
739             be.strerror());
740    }
741    BSOCK* ret =  init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
742    free_addresses(addr_list);
743    return ret;
744 }
745
746 /*
747  * Try to connect to host for max_retry_time at retry_time intervals.
748  */
749 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
750                     const char *name, char *host, char *service, int port,
751                     int verbose)
752 {
753    int i;
754    BSOCK *bsock;
755    int fatal = 0;
756
757    for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
758         i -= retry_interval) {
759       berrno be;
760       if (fatal || (jcr && job_canceled(jcr))) {
761          return NULL;
762       }
763       Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
764             name, host, port, be.strerror());
765       if (i < 0) {
766          i = 60 * 5;               /* complain again in 5 minutes */
767          if (verbose)
768             Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n"
769 "Retrying ...\n", name, host, port, be.strerror());
770       }
771       bmicrosleep(retry_interval, 0);
772       max_retry_time -= retry_interval;
773       if (max_retry_time <= 0) {
774          Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
775                name, host, port, be.strerror());
776          return NULL;
777       }
778    }
779    return bsock;
780 }
781
782
783 /*
784  * Return the string for the error that occurred
785  * on the socket. Only the first error is retained.
786  */
787 const char *bnet_strerror(BSOCK * bsock)
788 {
789    berrno be;
790    if (bsock->errmsg == NULL) {
791       bsock->errmsg = get_pool_memory(PM_MESSAGE);
792    }
793    pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
794    return bsock->errmsg;
795 }
796
797 /*
798  * Format and send a message
799  *  Returns: false on error
800  *           true  on success
801  */
802 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
803 {
804    va_list arg_ptr;
805    int maxlen;
806
807    if (bs->errors || bs->terminated) {
808       return false;
809    }
810    /* This probably won't work, but we vsnprintf, then if we
811     * get a negative length or a length greater than our buffer
812     * (depending on which library is used), the printf was truncated, so
813     * get a bigger buffer and try again.
814     */
815    for (;;) {
816       maxlen = sizeof_pool_memory(bs->msg) - 1;
817       va_start(arg_ptr, fmt);
818       bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
819       va_end(arg_ptr);
820       if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
821          break;
822       }
823       bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
824    }
825    return bnet_send(bs);
826 }
827
828 /*
829  * Set the network buffer size, suggested size is in size.
830  *  Actual size obtained is returned in bs->msglen
831  *
832  *  Returns: 0 on failure
833  *           1 on success
834  */
835 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
836 {
837    uint32_t dbuf_size, start_size;
838 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
839    int opt;
840
841    opt = IPTOS_THROUGHPUT;
842    setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
843 #endif
844
845    if (size != 0) {
846       dbuf_size = size;
847    } else {
848       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
849    }
850    start_size = dbuf_size;
851    if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
852       Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
853       return false;
854    }
855    if (rw & BNET_SETBUF_READ) {
856       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
857               SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
858          berrno be;
859          Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
860          dbuf_size -= TAPE_BSIZE;
861       }
862       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
863       if (dbuf_size != start_size) {
864          Qmsg1(bs->jcr, M_WARNING, 0,
865                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
866       }
867       if (dbuf_size % TAPE_BSIZE != 0) {
868          Qmsg1(bs->jcr, M_ABORT, 0,
869                _("Network buffer size %d not multiple of tape block size.\n"),
870                dbuf_size);
871       }
872    }
873    if (size != 0) {
874       dbuf_size = size;
875    } else {
876       dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
877    }
878    start_size = dbuf_size;
879    if (rw & BNET_SETBUF_WRITE) {
880       while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
881               SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
882          berrno be;
883          Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
884          dbuf_size -= TAPE_BSIZE;
885       }
886       Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
887       if (dbuf_size != start_size) {
888          Qmsg1(bs->jcr, M_WARNING, 0,
889                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
890       }
891       if (dbuf_size % TAPE_BSIZE != 0) {
892          Qmsg1(bs->jcr, M_ABORT, 0,
893                _("Network buffer size %d not multiple of tape block size.\n"),
894                dbuf_size);
895       }
896    }
897
898    bs->msglen = dbuf_size;
899    return true;
900 }
901
902 /*
903  * Send a network "signal" to the other end
904  *  This consists of sending a negative packet length
905  *
906  *  Returns: false on failure
907  *           true  on success
908  */
909 bool bnet_sig(BSOCK * bs, int sig)
910 {
911    bs->msglen = sig;
912    return bnet_send(bs);
913 }
914
915 /*
916  * Convert a network "signal" code into
917  * human readable ASCII.
918  */
919 const char *bnet_sig_to_ascii(BSOCK * bs)
920 {
921    static char buf[30];
922    switch (bs->msglen) {
923    case BNET_EOD:
924       return "BNET_EOD";           /* end of data stream */
925    case BNET_EOD_POLL:
926       return "BNET_EOD_POLL";
927    case BNET_STATUS:
928       return "BNET_STATUS";
929    case BNET_TERMINATE:
930       return "BNET_TERMINATE";     /* terminate connection */
931    case BNET_POLL:
932       return "BNET_POLL";
933    case BNET_HEARTBEAT:
934       return "BNET_HEARTBEAT";
935    case BNET_HB_RESPONSE:
936       return "BNET_HB_RESPONSE";
937    case BNET_PROMPT:
938       return "BNET_PROMPT";
939    default:
940       sprintf(buf, "Unknown sig %d", (int)bs->msglen);
941       return buf;
942    }
943 }
944
945
946 /* Initialize internal socket structure.
947  *  This probably should be done in net_open
948  */
949 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
950                   struct sockaddr *client_addr)
951 {
952    Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
953    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
954    memset(bsock, 0, sizeof(BSOCK));
955    bsock->fd = sockfd;
956    bsock->errors = 0;
957    bsock->msg = get_pool_memory(PM_MESSAGE);
958    bsock->errmsg = get_pool_memory(PM_MESSAGE);
959    bsock->who = bstrdup(who);
960    bsock->host = bstrdup(host);
961    bsock->port = port;
962    memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
963    /*
964     * ****FIXME**** reduce this to a few hours once
965     *   heartbeats are implemented
966     */
967    bsock->timeout = 60 * 60 * 6 * 24;   /* 6 days timeout */
968    bsock->jcr = jcr;
969    return bsock;
970 }
971
972 BSOCK *dup_bsock(BSOCK * osock)
973 {
974    BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
975    memcpy(bsock, osock, sizeof(BSOCK));
976    bsock->msg = get_pool_memory(PM_MESSAGE);
977    bsock->errmsg = get_pool_memory(PM_MESSAGE);
978    if (osock->who) {
979       bsock->who = bstrdup(osock->who);
980    }
981    if (osock->host) {
982       bsock->host = bstrdup(osock->host);
983    }
984    bsock->duped = true;
985    return bsock;
986 }
987
988 /* Close the network connection */
989 void bnet_close(BSOCK * bsock)
990 {
991    BSOCK *next;
992
993    for (; bsock != NULL; bsock = next) {
994       next = bsock->next;
995       if (!bsock->duped) {
996          if (bsock->timed_out) {
997             shutdown(bsock->fd, 2);     /* discard any pending I/O */
998          }
999          socketClose(bsock->fd);   /* normal close */
1000       }
1001       term_bsock(bsock);
1002    }
1003    return;
1004 }
1005
1006 void term_bsock(BSOCK * bsock)
1007 {
1008    if (bsock->msg) {
1009       free_pool_memory(bsock->msg);
1010       bsock->msg = NULL;
1011    } else {
1012       ASSERT(1 == 0);              /* double close */
1013    }
1014    if (bsock->errmsg) {
1015       free_pool_memory(bsock->errmsg);
1016       bsock->errmsg = NULL;
1017    }
1018    if (bsock->who) {
1019       free(bsock->who);
1020       bsock->who = NULL;
1021    }
1022    if (bsock->host) {
1023       free(bsock->host);
1024       bsock->host = NULL;
1025    }
1026    free(bsock);
1027 }