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