2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Network Utility Routines
33 * Adapted and enhanced for Bacula, originally written
34 * for inclusion in the Apcupsd package
44 extern time_t watchdog_time;
47 #define INADDR_NONE -1
50 #ifndef ENODATA /* not defined on BSD systems */
55 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
56 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
57 #define socketClose(fd) closesocket(fd)
59 #define socketRead(fd, buf, len) read(fd, buf, len)
60 #define socketWrite(fd, buf, len) write(fd, buf, len)
61 #define socketClose(fd) close(fd)
64 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
67 * Read a nbytes from the network.
68 * It is possible that the total bytes require in several
72 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
79 return (tls_bsock_readn(bsock, ptr, nbytes));
86 nread = socketRead(bsock->fd, ptr, nleft);
87 if (bsock->timed_out || bsock->terminated) {
94 if (errno == EAGAIN) {
95 bmicrosleep(0, 200000); /* try again in 200ms */
100 return nread; /* error, or EOF */
105 return nbytes - nleft; /* return >= 0 */
109 * Write nbytes to the network.
110 * It may require several writes.
113 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
115 int32_t nleft, nwritten;
118 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
119 if (nwritten != nbytes) {
121 bsock->b_errno = errno;
122 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
124 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
125 errno = bsock->b_errno;
134 return (tls_bsock_writen(bsock, ptr, nbytes));
136 #endif /* HAVE_TLS */
142 nwritten = socketWrite(bsock->fd, ptr, nleft);
143 if (bsock->timed_out || bsock->terminated) {
146 } while (nwritten == -1 && errno == EINTR);
148 * If connection is non-blocking, we will get EAGAIN, so
149 * use select() to keep from consuming all the CPU
152 if (nwritten == -1 && errno == EAGAIN) {
157 FD_SET((unsigned)bsock->fd, &fdset);
160 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
164 return nwritten; /* error */
169 return nbytes - nleft;
173 * Receive a message from the other end. Each message consists of
174 * two packets. The first is a header that contains the size
175 * of the data that follows in the second packet.
176 * Returns number of bytes read (may return zero)
177 * Returns -1 on signal (BNET_SIGNAL)
178 * Returns -2 on hard end of file (BNET_HARDEOF)
179 * Returns -3 on error (BNET_ERROR)
181 * Unfortunately, it is a bit complicated because we have these
184 * 2. Signal including end of data stream
185 * 3. Hard end of file
187 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
189 int32_t bnet_recv(BSOCK * bsock)
199 if (bsock->errors || bsock->terminated) {
203 bsock->read_seqno++; /* bump sequence number */
204 bsock->timer_start = watchdog_time; /* set start wait time */
205 bsock->timed_out = 0;
206 /* get data size -- in int32_t */
207 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
208 bsock->timer_start = 0; /* clear timer */
209 /* probably pipe broken because client died */
211 bsock->b_errno = ENODATA;
213 bsock->b_errno = errno;
216 return BNET_HARDEOF; /* assume hard EOF received */
218 bsock->timer_start = 0; /* clear timer */
219 if (nbytes != sizeof(int32_t)) {
221 bsock->b_errno = EIO;
222 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
223 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
227 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
229 if (pktsiz == 0) { /* No data transferred */
230 bsock->timer_start = 0; /* clear timer */
233 return 0; /* zero bytes read */
236 /* If signal or packet size too big */
237 if (pktsiz < 0 || pktsiz > 1000000) {
238 if (pktsiz > 0) { /* if packet too big */
239 Qmsg3(bsock->jcr, M_FATAL, 0,
240 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
241 bsock->who, bsock->host, bsock->port);
242 pktsiz = BNET_TERMINATE; /* hang up */
244 if (pktsiz == BNET_TERMINATE) {
245 bsock->terminated = 1;
247 bsock->timer_start = 0; /* clear timer */
248 bsock->b_errno = ENODATA;
249 bsock->msglen = pktsiz; /* signal code */
250 return BNET_SIGNAL; /* signal */
253 /* Make sure the buffer is big enough + one byte for EOS */
254 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
255 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
258 bsock->timer_start = watchdog_time; /* set start wait time */
259 bsock->timed_out = 0;
260 /* now read the actual data */
261 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
262 bsock->timer_start = 0; /* clear timer */
264 bsock->b_errno = ENODATA;
266 bsock->b_errno = errno;
269 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
270 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
273 bsock->timer_start = 0; /* clear timer */
275 bsock->msglen = nbytes;
276 if (nbytes != pktsiz) {
277 bsock->b_errno = EIO;
279 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
280 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
283 /* always add a zero by to properly terminate any
284 * string that was send to us. Note, we ensured above that the
285 * buffer is at least one byte longer than the message length.
287 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
288 sm_check(__FILE__, __LINE__, false);
289 return nbytes; /* return actual length of message */
294 * Return 1 if there are errors on this bsock or it is closed,
295 * i.e. stop communicating on this line.
297 bool is_bnet_stop(BSOCK * bsock)
299 return bsock->errors || bsock->terminated;
303 * Return number of errors on socket
305 int is_bnet_error(BSOCK * bsock)
307 errno = bsock->b_errno;
308 return bsock->errors;
312 * Call here after error during closing to suppress error
313 * messages which are due to the other end shutting down too.
315 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
317 bsock->suppress_error_msgs = flag;
322 * Transmit spooled data now to a BSOCK
324 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
329 ssize_t last = 0, size = 0;
332 rewind(bsock->spool_fd);
333 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
335 size += sizeof(int32_t);
336 bsock->msglen = ntohl(pktsiz);
337 if (bsock->msglen > 0) {
338 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
339 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
341 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
342 if (nbytes != (size_t) bsock->msglen) {
344 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
345 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
347 update_attr_spool_size(tsize - last);
351 if ((++count & 0x3F) == 0) {
352 update_attr_spool_size(size - last);
358 update_attr_spool_size(tsize - last);
359 if (ferror(bsock->spool_fd)) {
361 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
370 * Send a message over the network. The send consists of
371 * two network packets. The first is sends a 32 bit integer containing
372 * the length of the data packet which follows.
374 * Returns: false on failure
377 bool bnet_send(BSOCK *bsock)
379 return bsock->send();
383 bool bnet_send(BSOCK * bsock)
388 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
391 pktsiz = htonl((int32_t)bsock->msglen);
392 /* send int32_t containing size of data packet */
393 bsock->timer_start = watchdog_time; /* start timer */
394 bsock->timed_out = 0;
395 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
396 bsock->timer_start = 0; /* clear timer */
397 if (rc != sizeof(int32_t)) {
398 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
399 bsock->terminated = 1;
400 return false; /* ignore any errors */
404 bsock->b_errno = EIO;
406 bsock->b_errno = errno;
409 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
410 Qmsg4(bsock->jcr, M_ERROR, 0,
411 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
412 bsock->host, bsock->port, bnet_strerror(bsock));
415 Qmsg5(bsock->jcr, M_ERROR, 0,
416 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
417 sizeof(int32_t), bsock->who,
418 bsock->host, bsock->port, rc);
423 bsock->out_msg_no++; /* increment message number */
424 if (bsock->msglen <= 0) { /* length only? */
425 return true; /* yes, no data */
428 /* send data packet */
429 bsock->timer_start = watchdog_time; /* start timer */
430 bsock->timed_out = 0;
431 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
432 bsock->timer_start = 0; /* clear timer */
433 if (rc != bsock->msglen) {
436 bsock->b_errno = EIO;
438 bsock->b_errno = errno;
441 if (!bsock->suppress_error_msgs) {
442 Qmsg5(bsock->jcr, M_ERROR, 0,
443 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
444 bsock->msglen, bsock->who,
445 bsock->host, bsock->port, bnet_strerror(bsock));
448 Qmsg5(bsock->jcr, M_ERROR, 0,
449 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
450 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
459 * Establish a TLS connection -- server side
460 * Returns: true on success
464 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
468 tls = new_tls_connection(ctx, bsock->fd);
470 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
476 /* Initiate TLS Negotiation */
477 if (!tls_bsock_accept(bsock)) {
478 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
483 if (!tls_postconnect_verify_cn(tls, verify_list)) {
484 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
485 " Peer certificate did not match a required commonName\n"),
493 free_tls_connection(tls);
499 * Establish a TLS connection -- client side
500 * Returns: true on success
503 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
507 tls = new_tls_connection(ctx, bsock->fd);
509 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
515 /* Initiate TLS Negotiation */
516 if (!tls_bsock_connect(bsock)) {
520 if (!tls_postconnect_verify_host(tls, bsock->host)) {
521 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
527 free_tls_connection(tls);
532 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
534 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enabled but not configured.\n"));
537 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
539 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enable but not configured.\n"));
542 #endif /* HAVE_TLS */
545 * Wait for a specified time for data to appear on
546 * the BSOCK connection.
548 * Returns: 1 if data available
552 int bnet_wait_data(BSOCK * bsock, int sec)
558 FD_SET((unsigned)bsock->fd, &fdset);
562 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
563 case 0: /* timeout */
567 bsock->b_errno = errno;
568 if (errno == EINTR) {
571 return -1; /* error return */
580 * As above, but returns on interrupt
582 int bnet_wait_data_intr(BSOCK * bsock, int sec)
588 FD_SET((unsigned)bsock->fd, &fdset);
591 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
592 case 0: /* timeout */
596 bsock->b_errno = errno;
597 return -1; /* error return */
604 #ifndef NETDB_INTERNAL
605 #define NETDB_INTERNAL -1 /* See errno. */
607 #ifndef NETDB_SUCCESS
608 #define NETDB_SUCCESS 0 /* No problem. */
610 #ifndef HOST_NOT_FOUND
611 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
614 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
617 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
620 #define NO_DATA 4 /* Valid name, no data record of requested type. */
624 * Get human readable error for gethostbyname()
626 static const char *gethost_strerror()
635 msg = _("No problem.");
638 msg = _("Authoritative answer for host not found.");
641 msg = _("Non-authoritative for host not found, or ServerFail.");
644 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
647 msg = _("Valid name, no data record of resquested type.");
650 msg = _("Unknown error.");
658 static IPADDR *add_any(int family)
660 IPADDR *addr = New(IPADDR(family));
661 addr->set_type(IPADDR::R_MULTIPLE);
662 addr->set_addr_any();
666 static const char *resolv_host(int family, const char *host, dlist * addr_list)
672 #ifdef HAVE_GETHOSTBYNAME2
673 if ((hp = gethostbyname2(host, family)) == NULL) {
675 if ((hp = gethostbyname(host)) == NULL) {
677 /* may be the strerror give not the right result -:( */
678 errmsg = gethost_strerror();
683 for (p = hp->h_addr_list; *p != 0; p++) {
684 IPADDR *addr = New(IPADDR(hp->h_addrtype));
685 addr->set_type(IPADDR::R_MULTIPLE);
686 if (addr->get_family() == AF_INET) {
687 addr->set_addr4((struct in_addr*)*p);
691 addr->set_addr6((struct in6_addr*)*p);
694 addr_list->append(addr);
702 * i host = 0 mean INADDR_ANY only ipv4
704 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
706 struct in_addr inaddr;
710 struct in6_addr inaddr6;
713 dlist *addr_list = New(dlist(addr, &addr->link));
714 if (!host || host[0] == '\0') {
716 addr_list->append(add_any(family));
718 addr_list->append(add_any(AF_INET));
720 addr_list->append(add_any(AF_INET6));
723 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
724 addr = New(IPADDR(AF_INET));
725 addr->set_type(IPADDR::R_MULTIPLE);
726 addr->set_addr4(&inaddr);
727 addr_list->append(addr);
730 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
731 addr = New(IPADDR(AF_INET6));
732 addr->set_type(IPADDR::R_MULTIPLE);
733 addr->set_addr6(&inaddr6);
734 addr_list->append(addr);
739 errmsg = resolv_host(family, host, addr_list);
742 free_addresses(addr_list);
746 errmsg = resolv_host(AF_INET, host, addr_list);
749 errmsg = resolv_host(AF_INET6, host, addr_list);
754 free_addresses(addr_list);
763 * Open a TCP connection to the UPS network server
765 * Returns BSOCK * pointer on success
768 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
769 int port, int *fatal)
774 bool connected = false;
780 * Fill in the structure serv_addr with the address of
781 * the server that we want to connect with.
783 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
784 /* Note errstr is not malloc'ed */
785 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
787 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
793 foreach_dlist(ipaddr, addr_list) {
794 ipaddr->set_port_net(htons(port));
795 char allbuf[256 * 10];
797 Dmsg2(100, "Current %sAll %s\n",
798 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
799 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
800 /* Open a TCP socket */
801 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
805 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
806 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
810 * Keep socket from timing out from inactivity
812 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
814 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
817 /* connect to server */
818 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
829 free_addresses(addr_list);
834 * Keep socket from timing out from inactivity
835 * Do this a second time out of paranoia
837 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
839 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
842 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
843 free_addresses(addr_list);
848 * Try to connect to host for max_retry_time at retry_time intervals.
850 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
851 const char *name, char *host, char *service, int port,
858 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
859 i -= retry_interval) {
861 if (fatal || (jcr && job_canceled(jcr))) {
864 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
865 name, host, port, be.strerror());
867 i = 60 * 5; /* complain again in 5 minutes */
869 Qmsg4(jcr, M_WARNING, 0, _(
870 "Could not connect to %s on %s:%d. ERR=%s\n"
871 "Retrying ...\n"), name, host, port, be.strerror());
873 bmicrosleep(retry_interval, 0);
874 max_retry_time -= retry_interval;
875 if (max_retry_time <= 0) {
876 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
877 name, host, port, be.strerror());
886 * Return the string for the error that occurred
887 * on the socket. Only the first error is retained.
889 const char *bnet_strerror(BSOCK * bsock)
892 if (bsock->errmsg == NULL) {
893 bsock->errmsg = get_pool_memory(PM_MESSAGE);
895 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
896 return bsock->errmsg;
900 * Format and send a message
901 * Returns: false on error
904 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
909 if (bs->errors || bs->terminated) {
912 /* This probably won't work, but we vsnprintf, then if we
913 * get a negative length or a length greater than our buffer
914 * (depending on which library is used), the printf was truncated, so
915 * get a bigger buffer and try again.
918 maxlen = sizeof_pool_memory(bs->msg) - 1;
919 va_start(arg_ptr, fmt);
920 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
922 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
925 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
928 // return bnet_send(bs);
931 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
932 #if !defined(HAVE_WIN32)
933 if (bs->peer_addr.sin_family == 0) {
934 socklen_t salen = sizeof(bs->peer_addr);
935 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
936 if (rval < 0) return rval;
938 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
947 * Set the network buffer size, suggested size is in size.
948 * Actual size obtained is returned in bs->msglen
950 * Returns: 0 on failure
953 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
955 uint32_t dbuf_size, start_size;
956 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
959 opt = IPTOS_THROUGHPUT;
960 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
966 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
968 start_size = dbuf_size;
969 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
970 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
973 if (rw & BNET_SETBUF_READ) {
974 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
975 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
977 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
978 dbuf_size -= TAPE_BSIZE;
980 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
981 if (dbuf_size != start_size) {
982 Qmsg1(bs->jcr, M_WARNING, 0,
983 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
985 if (dbuf_size % TAPE_BSIZE != 0) {
986 Qmsg1(bs->jcr, M_ABORT, 0,
987 _("Network buffer size %d not multiple of tape block size.\n"),
994 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
996 start_size = dbuf_size;
997 if (rw & BNET_SETBUF_WRITE) {
998 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
999 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
1001 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
1002 dbuf_size -= TAPE_BSIZE;
1004 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
1005 if (dbuf_size != start_size) {
1006 Qmsg1(bs->jcr, M_WARNING, 0,
1007 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
1009 if (dbuf_size % TAPE_BSIZE != 0) {
1010 Qmsg1(bs->jcr, M_ABORT, 0,
1011 _("Network buffer size %d not multiple of tape block size.\n"),
1016 bs->msglen = dbuf_size;
1021 * Set socket non-blocking
1022 * Returns previous socket flag
1024 int bnet_set_nonblocking (BSOCK *bsock) {
1028 /* Get current flags */
1029 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1031 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1034 /* Set O_NONBLOCK flag */
1035 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
1037 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1040 bsock->blocking = 0;
1044 u_long ioctlArg = 1;
1046 flags = bsock->blocking;
1047 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1048 bsock->blocking = 0;
1055 * Set socket blocking
1056 * Returns previous socket flags
1058 int bnet_set_blocking (BSOCK *bsock)
1062 /* Get current flags */
1063 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1065 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1068 /* Set O_NONBLOCK flag */
1069 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1071 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1074 bsock->blocking = 1;
1078 u_long ioctlArg = 0;
1080 flags = bsock->blocking;
1081 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1082 bsock->blocking = 1;
1089 * Restores socket flags
1091 void bnet_restore_blocking (BSOCK *bsock, int flags)
1094 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1096 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1099 bsock->blocking = (flags & O_NONBLOCK);
1101 u_long ioctlArg = flags;
1103 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1104 bsock->blocking = 1;
1110 * Send a network "signal" to the other end
1111 * This consists of sending a negative packet length
1113 * Returns: false on failure
1116 bool bnet_sig(BSOCK * bs, int signal)
1118 return bs->signal(signal);
1122 * Convert a network "signal" code into
1123 * human readable ASCII.
1125 const char *bnet_sig_to_ascii(BSOCK * bs)
1127 static char buf[30];
1128 switch (bs->msglen) {
1130 return "BNET_EOD"; /* end of data stream */
1132 return "BNET_EOD_POLL";
1134 return "BNET_STATUS";
1135 case BNET_TERMINATE:
1136 return "BNET_TERMINATE"; /* terminate connection */
1139 case BNET_HEARTBEAT:
1140 return "BNET_HEARTBEAT";
1141 case BNET_HB_RESPONSE:
1142 return "BNET_HB_RESPONSE";
1144 return "BNET_PROMPT";
1146 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1152 /* Initialize internal socket structure.
1153 * This probably should be done in net_open
1155 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1156 struct sockaddr *client_addr)
1158 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1159 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1160 memset(bsock, 0, sizeof(BSOCK));
1164 bsock->blocking = 1;
1165 bsock->msg = get_pool_memory(PM_MESSAGE);
1166 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1167 bsock->who = bstrdup(who);
1168 bsock->host = bstrdup(host);
1170 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1171 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1173 * ****FIXME**** reduce this to a few hours once
1174 * heartbeats are implemented
1176 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1181 BSOCK *dup_bsock(BSOCK * osock)
1183 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1184 memcpy(bsock, osock, sizeof(BSOCK));
1185 bsock->msg = get_pool_memory(PM_MESSAGE);
1186 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1188 bsock->who = bstrdup(osock->who);
1191 bsock->host = bstrdup(osock->host);
1193 bsock->duped = true;
1197 /* Close the network connection */
1198 void bnet_close(BSOCK * bsock)
1202 for (; bsock != NULL; bsock = next) {
1204 if (!bsock->duped) {
1206 /* Shutdown tls cleanly. */
1208 tls_bsock_shutdown(bsock);
1209 free_tls_connection(bsock->tls);
1212 #endif /* HAVE_TLS */
1213 if (bsock->timed_out) {
1214 shutdown(bsock->fd, 2); /* discard any pending I/O */
1216 socketClose(bsock->fd); /* normal close */
1223 void term_bsock(BSOCK * bsock)
1226 free_pool_memory(bsock->msg);
1229 ASSERT(1 == 0); /* double close */
1231 if (bsock->errmsg) {
1232 free_pool_memory(bsock->errmsg);
1233 bsock->errmsg = NULL;