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