2 * Network Utility Routines
6 * Adapted and enhanced for Bacula, originally written
7 * for inclusion in the Apcupsd package
12 Copyright (C) 2000-2005 Kern Sibbald
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License
16 version 2 as amended with additional clauses defined in the
17 file LICENSE in the main source directory.
19 This program 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
22 the file LICENSE for additional details.
31 extern time_t watchdog_time;
34 #define INADDR_NONE -1
37 #ifndef ENODATA /* not defined on BSD systems */
42 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
43 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
44 #define socketClose(fd) closesocket(fd)
46 #define socketRead(fd, buf, len) read(fd, buf, len)
47 #define socketWrite(fd, buf, len) write(fd, buf, len)
48 #define socketClose(fd) close(fd)
51 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
54 * Read a nbytes from the network.
55 * It is possible that the total bytes require in several
59 static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
66 return (tls_bsock_readn(bsock, ptr, nbytes));
73 nread = socketRead(bsock->fd, ptr, nleft);
74 if (bsock->timed_out || bsock->terminated) {
81 if (errno == EAGAIN) {
82 bmicrosleep(0, 200000); /* try again in 200ms */
87 return nread; /* error, or EOF */
92 return nbytes - nleft; /* return >= 0 */
96 * Write nbytes to the network.
97 * It may require several writes.
100 static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
102 int32_t nleft, nwritten;
105 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
106 if (nwritten != nbytes) {
108 bsock->b_errno = errno;
109 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
111 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
112 errno = bsock->b_errno;
121 return (tls_bsock_writen(bsock, ptr, nbytes));
123 #endif /* HAVE_TLS */
129 nwritten = socketWrite(bsock->fd, ptr, nleft);
130 if (bsock->timed_out || bsock->terminated) {
133 } while (nwritten == -1 && errno == EINTR);
135 * If connection is non-blocking, we will get EAGAIN, so
136 * use select() to keep from consuming all the CPU
139 if (nwritten == -1 && errno == EAGAIN) {
144 FD_SET((unsigned)bsock->fd, &fdset);
147 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
151 return nwritten; /* error */
156 return nbytes - nleft;
160 * Receive a message from the other end. Each message consists of
161 * two packets. The first is a header that contains the size
162 * of the data that follows in the second packet.
163 * Returns number of bytes read (may return zero)
164 * Returns -1 on signal (BNET_SIGNAL)
165 * Returns -2 on hard end of file (BNET_HARDEOF)
166 * Returns -3 on error (BNET_ERROR)
168 * Unfortunately, it is a bit complicated because we have these
171 * 2. Signal including end of data stream
172 * 3. Hard end of file
174 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
176 int32_t bnet_recv(BSOCK * bsock)
186 if (bsock->errors || bsock->terminated) {
190 bsock->read_seqno++; /* bump sequence number */
191 bsock->timer_start = watchdog_time; /* set start wait time */
192 bsock->timed_out = 0;
193 /* get data size -- in int32_t */
194 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
195 bsock->timer_start = 0; /* clear timer */
196 /* probably pipe broken because client died */
198 bsock->b_errno = ENODATA;
200 bsock->b_errno = errno;
203 return BNET_HARDEOF; /* assume hard EOF received */
205 bsock->timer_start = 0; /* clear timer */
206 if (nbytes != sizeof(int32_t)) {
208 bsock->b_errno = EIO;
209 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
210 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
214 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
216 if (pktsiz == 0) { /* No data transferred */
217 bsock->timer_start = 0; /* clear timer */
220 return 0; /* zero bytes read */
223 /* If signal or packet size too big */
224 if (pktsiz < 0 || pktsiz > 1000000) {
225 if (pktsiz > 0) { /* if packet too big */
226 Qmsg3(bsock->jcr, M_FATAL, 0,
227 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
228 bsock->who, bsock->host, bsock->port);
229 pktsiz = BNET_TERMINATE; /* hang up */
231 if (pktsiz == BNET_TERMINATE) {
232 bsock->terminated = 1;
234 bsock->timer_start = 0; /* clear timer */
235 bsock->b_errno = ENODATA;
236 bsock->msglen = pktsiz; /* signal code */
237 return BNET_SIGNAL; /* signal */
240 /* Make sure the buffer is big enough + one byte for EOS */
241 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
242 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
245 bsock->timer_start = watchdog_time; /* set start wait time */
246 bsock->timed_out = 0;
247 /* now read the actual data */
248 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
249 bsock->timer_start = 0; /* clear timer */
251 bsock->b_errno = ENODATA;
253 bsock->b_errno = errno;
256 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
257 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
260 bsock->timer_start = 0; /* clear timer */
262 bsock->msglen = nbytes;
263 if (nbytes != pktsiz) {
264 bsock->b_errno = EIO;
266 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
267 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
270 /* always add a zero by to properly terminate any
271 * string that was send to us. Note, we ensured above that the
272 * buffer is at least one byte longer than the message length.
274 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
275 sm_check(__FILE__, __LINE__, false);
276 return nbytes; /* return actual length of message */
281 * Return 1 if there are errors on this bsock or it is closed,
282 * i.e. stop communicating on this line.
284 bool is_bnet_stop(BSOCK * bsock)
286 return bsock->errors || bsock->terminated;
290 * Return number of errors on socket
292 int is_bnet_error(BSOCK * bsock)
294 errno = bsock->b_errno;
295 return bsock->errors;
299 * Call here after error during closing to suppress error
300 * messages which are due to the other end shutting down too.
302 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
304 bsock->suppress_error_msgs = flag;
309 * Transmit spooled data now to a BSOCK
311 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
316 ssize_t last = 0, size = 0;
319 rewind(bsock->spool_fd);
320 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
322 size += sizeof(int32_t);
323 bsock->msglen = ntohl(pktsiz);
324 if (bsock->msglen > 0) {
325 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
326 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
328 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
329 if (nbytes != (size_t) bsock->msglen) {
331 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
332 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
334 update_attr_spool_size(tsize - last);
338 if ((++count & 0x3F) == 0) {
339 update_attr_spool_size(size - last);
345 update_attr_spool_size(tsize - last);
346 if (ferror(bsock->spool_fd)) {
348 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
357 * Send a message over the network. The send consists of
358 * two network packets. The first is sends a 32 bit integer containing
359 * the length of the data packet which follows.
361 * Returns: false on failure
364 bool bnet_send(BSOCK * bsock)
369 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
372 pktsiz = htonl((int32_t) bsock->msglen);
373 /* send int32_t containing size of data packet */
374 bsock->timer_start = watchdog_time; /* start timer */
375 bsock->timed_out = 0;
376 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
377 bsock->timer_start = 0; /* clear timer */
378 if (rc != sizeof(int32_t)) {
379 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
380 bsock->terminated = 1;
381 return false; /* ignore any errors */
385 bsock->b_errno = EIO;
387 bsock->b_errno = errno;
390 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
391 Qmsg4(bsock->jcr, M_ERROR, 0,
392 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
393 bsock->host, bsock->port, bnet_strerror(bsock));
396 Qmsg5(bsock->jcr, M_ERROR, 0,
397 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who,
398 bsock->host, bsock->port, bsock->msglen, rc);
403 bsock->out_msg_no++; /* increment message number */
404 if (bsock->msglen <= 0) { /* length only? */
405 return true; /* yes, no data */
408 /* send data packet */
409 bsock->timer_start = watchdog_time; /* start timer */
410 bsock->timed_out = 0;
411 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
412 bsock->timer_start = 0; /* clear timer */
413 if (rc != bsock->msglen) {
416 bsock->b_errno = EIO;
418 bsock->b_errno = errno;
421 if (!bsock->suppress_error_msgs) {
422 Qmsg5(bsock->jcr, M_ERROR, 0,
423 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
424 bsock->msglen, bsock->who,
425 bsock->host, bsock->port, bnet_strerror(bsock));
428 Qmsg5(bsock->jcr, M_ERROR, 0,
429 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
430 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
438 * Establish a TLS connection -- server side
439 * Returns: 1 on success
443 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
447 tls = new_tls_connection(ctx, bsock->fd);
449 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
455 /* Initiate TLS Negotiation */
456 if (!tls_bsock_accept(bsock)) {
457 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
462 if (!tls_postconnect_verify_cn(tls, verify_list)) {
463 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
464 " Peer certificate did not match a required commonName\n"),
473 free_tls_connection(tls);
479 * Establish a TLS connection -- client side
480 * Returns: 1 on success
483 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
487 tls = new_tls_connection(ctx, bsock->fd);
489 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
495 /* Initiate TLS Negotiation */
496 if (!tls_bsock_connect(bsock)) {
500 if (!tls_postconnect_verify_host(tls, bsock->host)) {
501 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
508 free_tls_connection(tls);
513 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
515 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
518 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
520 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
523 #endif /* HAVE_TLS */
526 * Wait for a specified time for data to appear on
527 * the BSOCK connection.
529 * Returns: 1 if data available
533 int bnet_wait_data(BSOCK * bsock, int sec)
539 FD_SET((unsigned)bsock->fd, &fdset);
543 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
544 case 0: /* timeout */
548 bsock->b_errno = errno;
549 if (errno == EINTR) {
552 return -1; /* error return */
561 * As above, but returns on interrupt
563 int bnet_wait_data_intr(BSOCK * bsock, int sec)
569 FD_SET((unsigned)bsock->fd, &fdset);
572 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
573 case 0: /* timeout */
577 bsock->b_errno = errno;
578 return -1; /* error return */
585 #ifndef NETDB_INTERNAL
586 #define NETDB_INTERNAL -1 /* See errno. */
588 #ifndef NETDB_SUCCESS
589 #define NETDB_SUCCESS 0 /* No problem. */
591 #ifndef HOST_NOT_FOUND
592 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
595 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
598 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
601 #define NO_DATA 4 /* Valid name, no data record of requested type. */
605 * Get human readable error for gethostbyname()
607 static const char *gethost_strerror()
616 msg = _("No problem.");
619 msg = _("Authoritative answer for host not found.");
622 msg = _("Non-authoritative for host not found, or ServerFail.");
625 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
628 msg = _("Valid name, no data record of resquested type.");
631 msg = _("Unknown error.");
639 static IPADDR *add_any(int family)
641 IPADDR *addr = New(IPADDR(family));
642 addr->set_type(IPADDR::R_MULTIPLE);
643 addr->set_addr_any();
647 static const char *resolv_host(int family, const char *host, dlist * addr_list)
653 #ifdef HAVE_GETHOSTBYNAME2
654 if ((hp = gethostbyname2(host, family)) == NULL) {
656 if ((hp = gethostbyname(host)) == NULL) {
658 /* may be the strerror give not the right result -:( */
659 errmsg = gethost_strerror();
664 for (p = hp->h_addr_list; *p != 0; p++) {
665 IPADDR *addr = New(IPADDR(hp->h_addrtype));
666 addr->set_type(IPADDR::R_MULTIPLE);
667 if (addr->get_family() == AF_INET) {
668 addr->set_addr4((struct in_addr*)*p);
672 addr->set_addr6((struct in6_addr*)*p);
675 addr_list->append(addr);
683 * i host = 0 mean INADDR_ANY only ipv4
685 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
687 struct in_addr inaddr;
691 struct in6_addr inaddr6;
694 dlist *addr_list = New(dlist(addr, &addr->link));
695 if (!host || host[0] == '\0') {
697 addr_list->append(add_any(family));
699 addr_list->append(add_any(AF_INET));
701 addr_list->append(add_any(AF_INET6));
704 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
705 addr = New(IPADDR(AF_INET));
706 addr->set_type(IPADDR::R_MULTIPLE);
707 addr->set_addr4(&inaddr);
708 addr_list->append(addr);
711 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
712 addr = New(IPADDR(AF_INET6));
713 addr->set_type(IPADDR::R_MULTIPLE);
714 addr->set_addr6(&inaddr6);
715 addr_list->append(addr);
720 errmsg = resolv_host(family, host, addr_list);
723 free_addresses(addr_list);
727 errmsg = resolv_host(AF_INET, host, addr_list);
730 errmsg = resolv_host(AF_INET6, host, addr_list);
735 free_addresses(addr_list);
744 * Open a TCP connection to the UPS network server
746 * Returns BSOCK * pointer on success
749 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
750 int port, int *fatal)
755 bool connected = false;
761 * Fill in the structure serv_addr with the address of
762 * the server that we want to connect with.
764 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
765 /* Note errstr is not malloc'ed */
766 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
768 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
774 foreach_dlist(ipaddr, addr_list) {
775 ipaddr->set_port_net(htons(port));
776 char allbuf[256 * 10];
778 Dmsg2(100, "Current %sAll %s\n",
779 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
780 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
781 /* Open a TCP socket */
782 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
786 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
787 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
791 * Keep socket from timing out from inactivity
793 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
795 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
798 /* connect to server */
799 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
810 free_addresses(addr_list);
815 * Keep socket from timing out from inactivity
816 * Do this a second time out of paranoia
818 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
820 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
823 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
824 free_addresses(addr_list);
829 * Try to connect to host for max_retry_time at retry_time intervals.
831 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
832 const char *name, char *host, char *service, int port,
839 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
840 i -= retry_interval) {
842 if (fatal || (jcr && job_canceled(jcr))) {
845 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
846 name, host, port, be.strerror());
848 i = 60 * 5; /* complain again in 5 minutes */
850 Qmsg4(jcr, M_WARNING, 0, _(
851 "Could not connect to %s on %s:%d. ERR=%s\n"
852 "Retrying ...\n"), name, host, port, be.strerror());
854 bmicrosleep(retry_interval, 0);
855 max_retry_time -= retry_interval;
856 if (max_retry_time <= 0) {
857 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
858 name, host, port, be.strerror());
867 * Return the string for the error that occurred
868 * on the socket. Only the first error is retained.
870 const char *bnet_strerror(BSOCK * bsock)
873 if (bsock->errmsg == NULL) {
874 bsock->errmsg = get_pool_memory(PM_MESSAGE);
876 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
877 return bsock->errmsg;
881 * Format and send a message
882 * Returns: false on error
885 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
890 if (bs->errors || bs->terminated) {
893 /* This probably won't work, but we vsnprintf, then if we
894 * get a negative length or a length greater than our buffer
895 * (depending on which library is used), the printf was truncated, so
896 * get a bigger buffer and try again.
899 maxlen = sizeof_pool_memory(bs->msg) - 1;
900 va_start(arg_ptr, fmt);
901 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
903 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
906 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
908 return bnet_send(bs);
912 * Set the network buffer size, suggested size is in size.
913 * Actual size obtained is returned in bs->msglen
915 * Returns: 0 on failure
918 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
920 uint32_t dbuf_size, start_size;
921 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
924 opt = IPTOS_THROUGHPUT;
925 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
931 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
933 start_size = dbuf_size;
934 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
935 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
938 if (rw & BNET_SETBUF_READ) {
939 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
940 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
942 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
943 dbuf_size -= TAPE_BSIZE;
945 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
946 if (dbuf_size != start_size) {
947 Qmsg1(bs->jcr, M_WARNING, 0,
948 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
950 if (dbuf_size % TAPE_BSIZE != 0) {
951 Qmsg1(bs->jcr, M_ABORT, 0,
952 _("Network buffer size %d not multiple of tape block size.\n"),
959 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
961 start_size = dbuf_size;
962 if (rw & BNET_SETBUF_WRITE) {
963 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
964 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
966 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
967 dbuf_size -= TAPE_BSIZE;
969 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
970 if (dbuf_size != start_size) {
971 Qmsg1(bs->jcr, M_WARNING, 0,
972 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
974 if (dbuf_size % TAPE_BSIZE != 0) {
975 Qmsg1(bs->jcr, M_ABORT, 0,
976 _("Network buffer size %d not multiple of tape block size.\n"),
981 bs->msglen = dbuf_size;
986 * Set socket non-blocking
987 * Returns previous socket flag
989 int bnet_set_nonblocking (BSOCK *bsock) {
993 /* Get current flags */
994 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
996 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
999 /* Set O_NONBLOCK flag */
1000 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
1002 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1005 bsock->blocking = 0;
1009 u_long ioctlArg = 1;
1011 flags = bsock->blocking;
1012 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1013 bsock->blocking = 0;
1020 * Set socket blocking
1021 * Returns previous socket flags
1023 int bnet_set_blocking (BSOCK *bsock)
1027 /* Get current flags */
1028 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1030 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1033 /* Set O_NONBLOCK flag */
1034 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1036 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1039 bsock->blocking = 1;
1043 u_long ioctlArg = 0;
1045 flags = bsock->blocking;
1046 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1047 bsock->blocking = 1;
1054 * Restores socket flags
1056 void bnet_restore_blocking (BSOCK *bsock, int flags)
1059 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1061 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1064 bsock->blocking = (flags & O_NONBLOCK);
1066 u_long ioctlArg = flags;
1068 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1069 bsock->blocking = 1;
1075 * Send a network "signal" to the other end
1076 * This consists of sending a negative packet length
1078 * Returns: false on failure
1081 bool bnet_sig(BSOCK * bs, int sig)
1084 if (sig == BNET_TERMINATE) {
1085 bs->suppress_error_msgs = true;
1087 return bnet_send(bs);
1091 * Convert a network "signal" code into
1092 * human readable ASCII.
1094 const char *bnet_sig_to_ascii(BSOCK * bs)
1096 static char buf[30];
1097 switch (bs->msglen) {
1099 return "BNET_EOD"; /* end of data stream */
1101 return "BNET_EOD_POLL";
1103 return "BNET_STATUS";
1104 case BNET_TERMINATE:
1105 return "BNET_TERMINATE"; /* terminate connection */
1108 case BNET_HEARTBEAT:
1109 return "BNET_HEARTBEAT";
1110 case BNET_HB_RESPONSE:
1111 return "BNET_HB_RESPONSE";
1113 return "BNET_PROMPT";
1115 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1121 /* Initialize internal socket structure.
1122 * This probably should be done in net_open
1124 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1125 struct sockaddr *client_addr)
1127 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1128 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1129 memset(bsock, 0, sizeof(BSOCK));
1133 bsock->blocking = 1;
1134 bsock->msg = get_pool_memory(PM_MESSAGE);
1135 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1136 bsock->who = bstrdup(who);
1137 bsock->host = bstrdup(host);
1139 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1141 * ****FIXME**** reduce this to a few hours once
1142 * heartbeats are implemented
1144 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1149 BSOCK *dup_bsock(BSOCK * osock)
1151 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1152 memcpy(bsock, osock, sizeof(BSOCK));
1153 bsock->msg = get_pool_memory(PM_MESSAGE);
1154 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1156 bsock->who = bstrdup(osock->who);
1159 bsock->host = bstrdup(osock->host);
1161 bsock->duped = true;
1165 /* Close the network connection */
1166 void bnet_close(BSOCK * bsock)
1170 for (; bsock != NULL; bsock = next) {
1172 if (!bsock->duped) {
1174 /* Shutdown tls cleanly. */
1176 tls_bsock_shutdown(bsock);
1177 free_tls_connection(bsock->tls);
1180 #endif /* HAVE_TLS */
1181 if (bsock->timed_out) {
1182 shutdown(bsock->fd, 2); /* discard any pending I/O */
1184 socketClose(bsock->fd); /* normal close */
1191 void term_bsock(BSOCK * bsock)
1194 free_pool_memory(bsock->msg);
1197 ASSERT(1 == 0); /* double close */
1199 if (bsock->errmsg) {
1200 free_pool_memory(bsock->errmsg);
1201 bsock->errmsg = NULL;