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