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