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"),
398 sizeof(int32_t), bsock->who,
399 bsock->host, bsock->port, rc);
404 bsock->out_msg_no++; /* increment message number */
405 if (bsock->msglen <= 0) { /* length only? */
406 return true; /* yes, no data */
409 /* send data packet */
410 bsock->timer_start = watchdog_time; /* start timer */
411 bsock->timed_out = 0;
412 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
413 bsock->timer_start = 0; /* clear timer */
414 if (rc != bsock->msglen) {
417 bsock->b_errno = EIO;
419 bsock->b_errno = errno;
422 if (!bsock->suppress_error_msgs) {
423 Qmsg5(bsock->jcr, M_ERROR, 0,
424 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
425 bsock->msglen, bsock->who,
426 bsock->host, bsock->port, bnet_strerror(bsock));
429 Qmsg5(bsock->jcr, M_ERROR, 0,
430 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
431 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
439 * Establish a TLS connection -- server side
440 * Returns: 1 on success
444 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
448 tls = new_tls_connection(ctx, bsock->fd);
450 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
456 /* Initiate TLS Negotiation */
457 if (!tls_bsock_accept(bsock)) {
458 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
463 if (!tls_postconnect_verify_cn(tls, verify_list)) {
464 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
465 " Peer certificate did not match a required commonName\n"),
474 free_tls_connection(tls);
480 * Establish a TLS connection -- client side
481 * Returns: 1 on success
484 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
488 tls = new_tls_connection(ctx, bsock->fd);
490 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
496 /* Initiate TLS Negotiation */
497 if (!tls_bsock_connect(bsock)) {
501 if (!tls_postconnect_verify_host(tls, bsock->host)) {
502 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
509 free_tls_connection(tls);
514 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
516 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
519 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
521 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
524 #endif /* HAVE_TLS */
527 * Wait for a specified time for data to appear on
528 * the BSOCK connection.
530 * Returns: 1 if data available
534 int bnet_wait_data(BSOCK * bsock, int sec)
540 FD_SET((unsigned)bsock->fd, &fdset);
544 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
545 case 0: /* timeout */
549 bsock->b_errno = errno;
550 if (errno == EINTR) {
553 return -1; /* error return */
562 * As above, but returns on interrupt
564 int bnet_wait_data_intr(BSOCK * bsock, int sec)
570 FD_SET((unsigned)bsock->fd, &fdset);
573 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
574 case 0: /* timeout */
578 bsock->b_errno = errno;
579 return -1; /* error return */
586 #ifndef NETDB_INTERNAL
587 #define NETDB_INTERNAL -1 /* See errno. */
589 #ifndef NETDB_SUCCESS
590 #define NETDB_SUCCESS 0 /* No problem. */
592 #ifndef HOST_NOT_FOUND
593 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
596 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
599 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
602 #define NO_DATA 4 /* Valid name, no data record of requested type. */
606 * Get human readable error for gethostbyname()
608 static const char *gethost_strerror()
617 msg = _("No problem.");
620 msg = _("Authoritative answer for host not found.");
623 msg = _("Non-authoritative for host not found, or ServerFail.");
626 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
629 msg = _("Valid name, no data record of resquested type.");
632 msg = _("Unknown error.");
640 static IPADDR *add_any(int family)
642 IPADDR *addr = New(IPADDR(family));
643 addr->set_type(IPADDR::R_MULTIPLE);
644 addr->set_addr_any();
648 static const char *resolv_host(int family, const char *host, dlist * addr_list)
654 #ifdef HAVE_GETHOSTBYNAME2
655 if ((hp = gethostbyname2(host, family)) == NULL) {
657 if ((hp = gethostbyname(host)) == NULL) {
659 /* may be the strerror give not the right result -:( */
660 errmsg = gethost_strerror();
665 for (p = hp->h_addr_list; *p != 0; p++) {
666 IPADDR *addr = New(IPADDR(hp->h_addrtype));
667 addr->set_type(IPADDR::R_MULTIPLE);
668 if (addr->get_family() == AF_INET) {
669 addr->set_addr4((struct in_addr*)*p);
673 addr->set_addr6((struct in6_addr*)*p);
676 addr_list->append(addr);
684 * i host = 0 mean INADDR_ANY only ipv4
686 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
688 struct in_addr inaddr;
692 struct in6_addr inaddr6;
695 dlist *addr_list = New(dlist(addr, &addr->link));
696 if (!host || host[0] == '\0') {
698 addr_list->append(add_any(family));
700 addr_list->append(add_any(AF_INET));
702 addr_list->append(add_any(AF_INET6));
705 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
706 addr = New(IPADDR(AF_INET));
707 addr->set_type(IPADDR::R_MULTIPLE);
708 addr->set_addr4(&inaddr);
709 addr_list->append(addr);
712 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
713 addr = New(IPADDR(AF_INET6));
714 addr->set_type(IPADDR::R_MULTIPLE);
715 addr->set_addr6(&inaddr6);
716 addr_list->append(addr);
721 errmsg = resolv_host(family, host, addr_list);
724 free_addresses(addr_list);
728 errmsg = resolv_host(AF_INET, host, addr_list);
731 errmsg = resolv_host(AF_INET6, host, addr_list);
736 free_addresses(addr_list);
745 * Open a TCP connection to the UPS network server
747 * Returns BSOCK * pointer on success
750 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
751 int port, int *fatal)
756 bool connected = false;
762 * Fill in the structure serv_addr with the address of
763 * the server that we want to connect with.
765 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
766 /* Note errstr is not malloc'ed */
767 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
769 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
775 foreach_dlist(ipaddr, addr_list) {
776 ipaddr->set_port_net(htons(port));
777 char allbuf[256 * 10];
779 Dmsg2(100, "Current %sAll %s\n",
780 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
781 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
782 /* Open a TCP socket */
783 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
787 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
788 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
792 * Keep socket from timing out from inactivity
794 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
796 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
799 /* connect to server */
800 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
811 free_addresses(addr_list);
816 * Keep socket from timing out from inactivity
817 * Do this a second time out of paranoia
819 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
821 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
824 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
825 free_addresses(addr_list);
830 * Try to connect to host for max_retry_time at retry_time intervals.
832 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
833 const char *name, char *host, char *service, int port,
840 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
841 i -= retry_interval) {
843 if (fatal || (jcr && job_canceled(jcr))) {
846 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
847 name, host, port, be.strerror());
849 i = 60 * 5; /* complain again in 5 minutes */
851 Qmsg4(jcr, M_WARNING, 0, _(
852 "Could not connect to %s on %s:%d. ERR=%s\n"
853 "Retrying ...\n"), name, host, port, be.strerror());
855 bmicrosleep(retry_interval, 0);
856 max_retry_time -= retry_interval;
857 if (max_retry_time <= 0) {
858 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
859 name, host, port, be.strerror());
868 * Return the string for the error that occurred
869 * on the socket. Only the first error is retained.
871 const char *bnet_strerror(BSOCK * bsock)
874 if (bsock->errmsg == NULL) {
875 bsock->errmsg = get_pool_memory(PM_MESSAGE);
877 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
878 return bsock->errmsg;
882 * Format and send a message
883 * Returns: false on error
886 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
891 if (bs->errors || bs->terminated) {
894 /* This probably won't work, but we vsnprintf, then if we
895 * get a negative length or a length greater than our buffer
896 * (depending on which library is used), the printf was truncated, so
897 * get a bigger buffer and try again.
900 maxlen = sizeof_pool_memory(bs->msg) - 1;
901 va_start(arg_ptr, fmt);
902 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
904 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
907 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
909 return bnet_send(bs);
913 * Set the network buffer size, suggested size is in size.
914 * Actual size obtained is returned in bs->msglen
916 * Returns: 0 on failure
919 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
921 uint32_t dbuf_size, start_size;
922 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
925 opt = IPTOS_THROUGHPUT;
926 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
932 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
934 start_size = dbuf_size;
935 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
936 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
939 if (rw & BNET_SETBUF_READ) {
940 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
941 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
943 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
944 dbuf_size -= TAPE_BSIZE;
946 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
947 if (dbuf_size != start_size) {
948 Qmsg1(bs->jcr, M_WARNING, 0,
949 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
951 if (dbuf_size % TAPE_BSIZE != 0) {
952 Qmsg1(bs->jcr, M_ABORT, 0,
953 _("Network buffer size %d not multiple of tape block size.\n"),
960 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
962 start_size = dbuf_size;
963 if (rw & BNET_SETBUF_WRITE) {
964 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
965 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
967 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
968 dbuf_size -= TAPE_BSIZE;
970 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
971 if (dbuf_size != start_size) {
972 Qmsg1(bs->jcr, M_WARNING, 0,
973 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
975 if (dbuf_size % TAPE_BSIZE != 0) {
976 Qmsg1(bs->jcr, M_ABORT, 0,
977 _("Network buffer size %d not multiple of tape block size.\n"),
982 bs->msglen = dbuf_size;
987 * Set socket non-blocking
988 * Returns previous socket flag
990 int bnet_set_nonblocking (BSOCK *bsock) {
994 /* Get current flags */
995 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
997 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1000 /* Set O_NONBLOCK flag */
1001 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
1003 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1006 bsock->blocking = 0;
1010 u_long ioctlArg = 1;
1012 flags = bsock->blocking;
1013 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1014 bsock->blocking = 0;
1021 * Set socket blocking
1022 * Returns previous socket flags
1024 int bnet_set_blocking (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 = 1;
1044 u_long ioctlArg = 0;
1046 flags = bsock->blocking;
1047 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1048 bsock->blocking = 1;
1055 * Restores socket flags
1057 void bnet_restore_blocking (BSOCK *bsock, int flags)
1060 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1062 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1065 bsock->blocking = (flags & O_NONBLOCK);
1067 u_long ioctlArg = flags;
1069 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1070 bsock->blocking = 1;
1076 * Send a network "signal" to the other end
1077 * This consists of sending a negative packet length
1079 * Returns: false on failure
1082 bool bnet_sig(BSOCK * bs, int sig)
1085 if (sig == BNET_TERMINATE) {
1086 bs->suppress_error_msgs = true;
1088 return bnet_send(bs);
1092 * Convert a network "signal" code into
1093 * human readable ASCII.
1095 const char *bnet_sig_to_ascii(BSOCK * bs)
1097 static char buf[30];
1098 switch (bs->msglen) {
1100 return "BNET_EOD"; /* end of data stream */
1102 return "BNET_EOD_POLL";
1104 return "BNET_STATUS";
1105 case BNET_TERMINATE:
1106 return "BNET_TERMINATE"; /* terminate connection */
1109 case BNET_HEARTBEAT:
1110 return "BNET_HEARTBEAT";
1111 case BNET_HB_RESPONSE:
1112 return "BNET_HB_RESPONSE";
1114 return "BNET_PROMPT";
1116 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1122 /* Initialize internal socket structure.
1123 * This probably should be done in net_open
1125 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1126 struct sockaddr *client_addr)
1128 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1129 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1130 memset(bsock, 0, sizeof(BSOCK));
1134 bsock->blocking = 1;
1135 bsock->msg = get_pool_memory(PM_MESSAGE);
1136 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1137 bsock->who = bstrdup(who);
1138 bsock->host = bstrdup(host);
1140 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1142 * ****FIXME**** reduce this to a few hours once
1143 * heartbeats are implemented
1145 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1150 BSOCK *dup_bsock(BSOCK * osock)
1152 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1153 memcpy(bsock, osock, sizeof(BSOCK));
1154 bsock->msg = get_pool_memory(PM_MESSAGE);
1155 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1157 bsock->who = bstrdup(osock->who);
1160 bsock->host = bstrdup(osock->host);
1162 bsock->duped = true;
1166 /* Close the network connection */
1167 void bnet_close(BSOCK * bsock)
1171 for (; bsock != NULL; bsock = next) {
1173 if (!bsock->duped) {
1175 /* Shutdown tls cleanly. */
1177 tls_bsock_shutdown(bsock);
1178 free_tls_connection(bsock->tls);
1181 #endif /* HAVE_TLS */
1182 if (bsock->timed_out) {
1183 shutdown(bsock->fd, 2); /* discard any pending I/O */
1185 socketClose(bsock->fd); /* normal close */
1192 void term_bsock(BSOCK * bsock)
1195 free_pool_memory(bsock->msg);
1198 ASSERT(1 == 0); /* double close */
1200 if (bsock->errmsg) {
1201 free_pool_memory(bsock->errmsg);
1202 bsock->errmsg = NULL;