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 ammended 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));
74 nread = socketRead(bsock->fd, ptr, nleft);
75 if (bsock->timed_out || bsock->terminated) {
78 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
80 return nread; /* error, or EOF */
85 return nbytes - nleft; /* return >= 0 */
89 * Write nbytes to the network.
90 * It may require several writes.
93 static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
95 int32_t nleft, nwritten;
98 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
99 if (nwritten != nbytes) {
101 bsock->b_errno = errno;
102 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
104 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
105 errno = bsock->b_errno;
114 return (tls_bsock_writen(bsock, ptr, nbytes));
116 #endif /* HAVE_TLS */
122 nwritten = socketWrite(bsock->fd, ptr, nleft);
123 if (bsock->timed_out || bsock->terminated) {
126 } while (nwritten == -1 && errno == EINTR);
128 * If connection is non-blocking, we will get EAGAIN, so
129 * use select() to keep from consuming all the CPU
132 if (nwritten == -1 && errno == EAGAIN) {
137 FD_SET((unsigned)bsock->fd, &fdset);
140 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
144 return nwritten; /* error */
149 return nbytes - nleft;
153 * Receive a message from the other end. Each message consists of
154 * two packets. The first is a header that contains the size
155 * of the data that follows in the second packet.
156 * Returns number of bytes read (may return zero)
157 * Returns -1 on signal (BNET_SIGNAL)
158 * Returns -2 on hard end of file (BNET_HARDEOF)
159 * Returns -3 on error (BNET_ERROR)
161 * Unfortunately, it is a bit complicated because we have these
164 * 2. Signal including end of data stream
165 * 3. Hard end of file
167 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
169 int32_t bnet_recv(BSOCK * bsock)
174 ASSERT(bsock != NULL);
177 if (bsock->errors || bsock->terminated) {
181 bsock->read_seqno++; /* bump sequence number */
182 bsock->timer_start = watchdog_time; /* set start wait time */
183 bsock->timed_out = 0;
184 /* get data size -- in int32_t */
185 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
186 bsock->timer_start = 0; /* clear timer */
187 /* probably pipe broken because client died */
189 bsock->b_errno = ENODATA;
191 bsock->b_errno = errno;
194 return BNET_HARDEOF; /* assume hard EOF received */
196 bsock->timer_start = 0; /* clear timer */
197 if (nbytes != sizeof(int32_t)) {
199 bsock->b_errno = EIO;
200 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
201 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
205 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
207 if (pktsiz == 0) { /* No data transferred */
208 bsock->timer_start = 0; /* clear timer */
211 return 0; /* zero bytes read */
214 /* If signal or packet size too big */
215 if (pktsiz < 0 || pktsiz > 1000000) {
216 if (pktsiz > 0) { /* if packet too big */
217 Qmsg3(bsock->jcr, M_FATAL, 0,
218 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
219 bsock->who, bsock->host, bsock->port);
220 pktsiz = BNET_TERMINATE; /* hang up */
222 if (pktsiz == BNET_TERMINATE) {
223 bsock->terminated = 1;
225 bsock->timer_start = 0; /* clear timer */
226 bsock->b_errno = ENODATA;
227 bsock->msglen = pktsiz; /* signal code */
228 return BNET_SIGNAL; /* signal */
231 /* Make sure the buffer is big enough + one byte for EOS */
232 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
233 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
236 bsock->timer_start = watchdog_time; /* set start wait time */
237 bsock->timed_out = 0;
238 /* now read the actual data */
239 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
240 bsock->timer_start = 0; /* clear timer */
242 bsock->b_errno = ENODATA;
244 bsock->b_errno = errno;
247 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
248 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
251 bsock->timer_start = 0; /* clear timer */
253 bsock->msglen = nbytes;
254 if (nbytes != pktsiz) {
255 bsock->b_errno = EIO;
257 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
258 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
261 /* always add a zero by to properly terminate any
262 * string that was send to us. Note, we ensured above that the
263 * buffer is at least one byte longer than the message length.
265 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
266 sm_check(__FILE__, __LINE__, false);
267 return nbytes; /* return actual length of message */
272 * Return 1 if there are errors on this bsock or it is closed,
273 * i.e. stop communicating on this line.
275 bool is_bnet_stop(BSOCK * bsock)
277 return bsock->errors || bsock->terminated;
281 * Return number of errors on socket
283 int is_bnet_error(BSOCK * bsock)
285 errno = bsock->b_errno;
286 return bsock->errors;
290 * Call here after error during closing to suppress error
291 * messages which are due to the other end shutting down too.
293 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
295 bsock->suppress_error_msgs = flag;
300 * Transmit spooled data now to a BSOCK
302 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
307 ssize_t last = 0, size = 0;
310 rewind(bsock->spool_fd);
311 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
313 size += sizeof(int32_t);
314 bsock->msglen = ntohl(pktsiz);
315 if (bsock->msglen > 0) {
316 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
317 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
319 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
320 if (nbytes != (size_t) bsock->msglen) {
322 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
323 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
325 update_attr_spool_size(tsize - last);
329 if ((++count & 0x3F) == 0) {
330 update_attr_spool_size(size - last);
336 update_attr_spool_size(tsize - last);
337 if (ferror(bsock->spool_fd)) {
339 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
348 * Send a message over the network. The send consists of
349 * two network packets. The first is sends a 32 bit integer containing
350 * the length of the data packet which follows.
352 * Returns: false on failure
355 bool bnet_send(BSOCK * bsock)
360 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
363 pktsiz = htonl((int32_t) bsock->msglen);
364 /* send int32_t containing size of data packet */
365 bsock->timer_start = watchdog_time; /* start timer */
366 bsock->timed_out = 0;
367 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
368 bsock->timer_start = 0; /* clear timer */
369 if (rc != sizeof(int32_t)) {
370 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
371 bsock->terminated = 1;
372 return false; /* ignore any errors */
376 bsock->b_errno = EIO;
378 bsock->b_errno = errno;
381 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
382 Qmsg4(bsock->jcr, M_ERROR, 0,
383 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
384 bsock->host, bsock->port, bnet_strerror(bsock));
387 Qmsg5(bsock->jcr, M_ERROR, 0,
388 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who,
389 bsock->host, bsock->port, bsock->msglen, rc);
394 bsock->out_msg_no++; /* increment message number */
395 if (bsock->msglen <= 0) { /* length only? */
396 return true; /* yes, no data */
399 /* send data packet */
400 bsock->timer_start = watchdog_time; /* start timer */
401 bsock->timed_out = 0;
402 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
403 bsock->timer_start = 0; /* clear timer */
404 if (rc != bsock->msglen) {
407 bsock->b_errno = EIO;
409 bsock->b_errno = errno;
412 if (!bsock->suppress_error_msgs) {
413 Qmsg5(bsock->jcr, M_ERROR, 0,
414 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
415 bsock->msglen, bsock->who,
416 bsock->host, bsock->port, bnet_strerror(bsock));
419 Qmsg5(bsock->jcr, M_ERROR, 0,
420 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
421 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
429 * Establish a TLS connection -- server side
430 * Returns: 1 on success
434 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
438 tls = new_tls_connection(ctx, bsock->fd);
440 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
446 /* Initiate TLS Negotiation */
447 if (!tls_bsock_accept(bsock)) {
448 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
453 if (!tls_postconnect_verify_cn(tls, verify_list)) {
454 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
455 " Peer certificate did not match a required commonName\n"),
464 free_tls_connection(tls);
470 * Establish a TLS connection -- client side
471 * Returns: 1 on success
474 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
478 tls = new_tls_connection(ctx, bsock->fd);
480 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
486 /* Initiate TLS Negotiation */
487 if (!tls_bsock_connect(bsock)) {
491 if (!tls_postconnect_verify_host(tls, bsock->host)) {
492 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
499 free_tls_connection(tls);
504 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
506 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
509 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
511 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
514 #endif /* HAVE_TLS */
517 * Wait for a specified time for data to appear on
518 * the BSOCK connection.
520 * Returns: 1 if data available
524 int bnet_wait_data(BSOCK * bsock, int sec)
530 FD_SET((unsigned)bsock->fd, &fdset);
534 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
535 case 0: /* timeout */
539 bsock->b_errno = errno;
540 if (errno == EINTR || errno == EAGAIN) {
543 return -1; /* error return */
552 * As above, but returns on interrupt
554 int bnet_wait_data_intr(BSOCK * bsock, int sec)
560 FD_SET((unsigned)bsock->fd, &fdset);
563 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
564 case 0: /* timeout */
568 bsock->b_errno = errno;
569 return -1; /* error return */
576 #ifndef NETDB_INTERNAL
577 #define NETDB_INTERNAL -1 /* See errno. */
579 #ifndef NETDB_SUCCESS
580 #define NETDB_SUCCESS 0 /* No problem. */
582 #ifndef HOST_NOT_FOUND
583 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
586 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
589 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
592 #define NO_DATA 4 /* Valid name, no data record of requested type. */
596 * Get human readable error for gethostbyname()
598 static const char *gethost_strerror()
610 msg = "Authoritative answer for host not found.";
613 msg = "Non-authoritative for host not found, or ServerFail.";
616 msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
619 msg = "Valid name, no data record of resquested type.";
622 msg = "Unknown error.";
630 static IPADDR *add_any(int family)
632 IPADDR *addr = New(IPADDR(family));
633 addr->set_type(IPADDR::R_MULTIPLE);
634 addr->set_addr_any();
638 static const char *resolv_host(int family, const char *host, dlist * addr_list)
644 #ifdef HAVE_GETHOSTBYNAME2
645 if ((hp = gethostbyname2(host, family)) == NULL) {
647 if ((hp = gethostbyname(host)) == NULL) {
649 /* may be the strerror give not the right result -:( */
650 errmsg = gethost_strerror();
655 for (p = hp->h_addr_list; *p != 0; p++) {
656 IPADDR *addr = New(IPADDR(hp->h_addrtype));
657 addr->set_type(IPADDR::R_MULTIPLE);
658 if (addr->get_family() == AF_INET) {
659 addr->set_addr4((struct in_addr*)*p);
663 addr->set_addr6((struct in6_addr*)*p);
666 addr_list->append(addr);
674 * i host = 0 mean INADDR_ANY only ipv4
676 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
678 struct in_addr inaddr;
682 struct in6_addr inaddr6;
685 dlist *addr_list = New(dlist(addr, &addr->link));
686 if (!host || host[0] == '\0') {
688 addr_list->append(add_any(family));
690 addr_list->append(add_any(AF_INET));
692 addr_list->append(add_any(AF_INET6));
695 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
696 addr = New(IPADDR(AF_INET));
697 addr->set_type(IPADDR::R_MULTIPLE);
698 addr->set_addr4(&inaddr);
699 addr_list->append(addr);
702 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
703 addr = New(IPADDR(AF_INET6));
704 addr->set_type(IPADDR::R_MULTIPLE);
705 addr->set_addr6(&inaddr6);
706 addr_list->append(addr);
711 errmsg = resolv_host(family, host, addr_list);
714 free_addresses(addr_list);
718 errmsg = resolv_host(AF_INET, host, addr_list);
721 errmsg = resolv_host(AF_INET6, host, addr_list);
726 free_addresses(addr_list);
735 * Open a TCP connection to the UPS network server
737 * Returns BSOCK * pointer on success
740 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
741 int port, int *fatal)
746 bool connected = false;
752 * Fill in the structure serv_addr with the address of
753 * the server that we want to connect with.
755 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
756 /* Note errstr is not malloc'ed */
757 Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
759 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
765 foreach_dlist(ipaddr, addr_list) {
766 ipaddr->set_port_net(htons(port));
767 char allbuf[256 * 10];
769 Dmsg2(100, "Current %sAll %s\n",
770 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
771 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
772 /* Open a TCP socket */
773 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
777 Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
778 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
782 * Keep socket from timing out from inactivity
784 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
786 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
789 /* connect to server */
790 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
801 free_addresses(addr_list);
806 * Keep socket from timing out from inactivity
807 * Do this a second time out of paranoia
809 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
811 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
814 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
815 free_addresses(addr_list);
820 * Try to connect to host for max_retry_time at retry_time intervals.
822 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
823 const char *name, char *host, char *service, int port,
830 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
831 i -= retry_interval) {
833 if (fatal || (jcr && job_canceled(jcr))) {
836 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
837 name, host, port, be.strerror());
839 i = 60 * 5; /* complain again in 5 minutes */
841 Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n"
842 "Retrying ...\n", name, host, port, be.strerror());
844 bmicrosleep(retry_interval, 0);
845 max_retry_time -= retry_interval;
846 if (max_retry_time <= 0) {
847 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
848 name, host, port, be.strerror());
857 * Return the string for the error that occurred
858 * on the socket. Only the first error is retained.
860 const char *bnet_strerror(BSOCK * bsock)
863 if (bsock->errmsg == NULL) {
864 bsock->errmsg = get_pool_memory(PM_MESSAGE);
866 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
867 return bsock->errmsg;
871 * Format and send a message
872 * Returns: false on error
875 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
880 if (bs->errors || bs->terminated) {
883 /* This probably won't work, but we vsnprintf, then if we
884 * get a negative length or a length greater than our buffer
885 * (depending on which library is used), the printf was truncated, so
886 * get a bigger buffer and try again.
889 maxlen = sizeof_pool_memory(bs->msg) - 1;
890 va_start(arg_ptr, fmt);
891 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
893 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
896 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
898 return bnet_send(bs);
902 * Set the network buffer size, suggested size is in size.
903 * Actual size obtained is returned in bs->msglen
905 * Returns: 0 on failure
908 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
910 uint32_t dbuf_size, start_size;
911 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
914 opt = IPTOS_THROUGHPUT;
915 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
921 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
923 start_size = dbuf_size;
924 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
925 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
928 if (rw & BNET_SETBUF_READ) {
929 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
930 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
932 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
933 dbuf_size -= TAPE_BSIZE;
935 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
936 if (dbuf_size != start_size) {
937 Qmsg1(bs->jcr, M_WARNING, 0,
938 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
940 if (dbuf_size % TAPE_BSIZE != 0) {
941 Qmsg1(bs->jcr, M_ABORT, 0,
942 _("Network buffer size %d not multiple of tape block size.\n"),
949 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
951 start_size = dbuf_size;
952 if (rw & BNET_SETBUF_WRITE) {
953 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
954 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
956 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
957 dbuf_size -= TAPE_BSIZE;
959 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
960 if (dbuf_size != start_size) {
961 Qmsg1(bs->jcr, M_WARNING, 0,
962 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
964 if (dbuf_size % TAPE_BSIZE != 0) {
965 Qmsg1(bs->jcr, M_ABORT, 0,
966 _("Network buffer size %d not multiple of tape block size.\n"),
971 bs->msglen = dbuf_size;
976 * Set socket non-blocking
977 * Returns previous socket flag
979 int bnet_set_nonblocking (BSOCK *bsock) {
983 /* Get current flags */
984 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
986 Emsg1(M_ABORT, 0, "fcntl F_GETFL error. ERR=%s\n", be.strerror());
989 /* Set O_NONBLOCK flag */
990 if((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
992 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", be.strerror());
1001 flags = bsock->blocking;
1002 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1003 bsock->blocking = 0;
1010 * Set socket blocking
1011 * Returns previous socket flags
1013 int bnet_set_blocking (BSOCK *bsock) {
1016 /* Get current flags */
1017 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1019 Emsg1(M_ABORT, 0, "fcntl F_GETFL error. ERR=%s\n", be.strerror());
1022 /* Set O_NONBLOCK flag */
1023 if((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1025 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", be.strerror());
1028 bsock->blocking = 1;
1032 u_long ioctlArg = 0;
1034 flags = bsock->blocking;
1035 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1036 bsock->blocking = 1;
1043 * Restores socket flags
1045 void bnet_restore_blocking (BSOCK *bsock, int flags) {
1047 if((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1049 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", be.strerror());
1052 bsock->blocking = (flags & O_NONBLOCK);
1054 u_long ioctlArg = flags;
1056 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1057 bsock->blocking = 1;
1063 * Send a network "signal" to the other end
1064 * This consists of sending a negative packet length
1066 * Returns: false on failure
1069 bool bnet_sig(BSOCK * bs, int sig)
1072 if (sig == BNET_TERMINATE) {
1073 bs->suppress_error_msgs = true;
1075 return bnet_send(bs);
1079 * Convert a network "signal" code into
1080 * human readable ASCII.
1082 const char *bnet_sig_to_ascii(BSOCK * bs)
1084 static char buf[30];
1085 switch (bs->msglen) {
1087 return "BNET_EOD"; /* end of data stream */
1089 return "BNET_EOD_POLL";
1091 return "BNET_STATUS";
1092 case BNET_TERMINATE:
1093 return "BNET_TERMINATE"; /* terminate connection */
1096 case BNET_HEARTBEAT:
1097 return "BNET_HEARTBEAT";
1098 case BNET_HB_RESPONSE:
1099 return "BNET_HB_RESPONSE";
1101 return "BNET_PROMPT";
1103 sprintf(buf, "Unknown sig %d", (int)bs->msglen);
1109 /* Initialize internal socket structure.
1110 * This probably should be done in net_open
1112 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1113 struct sockaddr *client_addr)
1115 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1116 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1117 memset(bsock, 0, sizeof(BSOCK));
1121 bsock->blocking = 1;
1122 bsock->msg = get_pool_memory(PM_MESSAGE);
1123 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1124 bsock->who = bstrdup(who);
1125 bsock->host = bstrdup(host);
1127 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1129 * ****FIXME**** reduce this to a few hours once
1130 * heartbeats are implemented
1132 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1137 BSOCK *dup_bsock(BSOCK * osock)
1139 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1140 memcpy(bsock, osock, sizeof(BSOCK));
1141 bsock->msg = get_pool_memory(PM_MESSAGE);
1142 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1144 bsock->who = bstrdup(osock->who);
1147 bsock->host = bstrdup(osock->host);
1149 bsock->duped = true;
1153 /* Close the network connection */
1154 void bnet_close(BSOCK * bsock)
1158 for (; bsock != NULL; bsock = next) {
1160 if (!bsock->duped) {
1162 /* Shutdown tls cleanly. */
1164 tls_bsock_shutdown(bsock);
1165 free_tls_connection(bsock->tls);
1168 #endif /* HAVE_TLS */
1169 if (bsock->timed_out) {
1170 shutdown(bsock->fd, 2); /* discard any pending I/O */
1172 socketClose(bsock->fd); /* normal close */
1179 void term_bsock(BSOCK * bsock)
1182 free_pool_memory(bsock->msg);
1185 ASSERT(1 == 0); /* double close */
1187 if (bsock->errmsg) {
1188 free_pool_memory(bsock->errmsg);
1189 bsock->errmsg = NULL;