2 * Network Utility Routines
6 * Adapted and enhanced for Bacula, originally written
7 * for inclusion in the Apcupsd package
12 Copyright (C) 2000-2004 Kern Sibbald
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2.1 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
36 extern time_t watchdog_time;
39 #define INADDR_NONE -1
42 #ifndef ENODATA /* not defined on BSD systems */
47 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
48 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
49 #define socketClose(fd) closesocket(fd)
51 #define socketRead(fd, buf, len) read(fd, buf, len)
52 #define socketWrite(fd, buf, len) write(fd, buf, len)
53 #define socketClose(fd) close(fd)
56 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
59 * Read a nbytes from the network.
60 * It is possible that the total bytes require in several
64 static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
71 return (tls_bsock_readn(bsock, ptr, nbytes));
79 nread = socketRead(bsock->fd, ptr, nleft);
80 if (bsock->timed_out || bsock->terminated) {
83 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
85 return nread; /* error, or EOF */
90 return nbytes - nleft; /* return >= 0 */
94 * Write nbytes to the network.
95 * It may require several writes.
98 static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
100 int32_t nleft, nwritten;
103 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
104 if (nwritten != nbytes) {
106 bsock->b_errno = errno;
107 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
109 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
110 errno = bsock->b_errno;
119 return (tls_bsock_writen(bsock, ptr, nbytes));
121 #endif /* HAVE_TLS */
127 nwritten = socketWrite(bsock->fd, ptr, nleft);
128 if (bsock->timed_out || bsock->terminated) {
131 } while (nwritten == -1 && errno == EINTR);
133 * If connection is non-blocking, we will get EAGAIN, so
134 * use select() to keep from consuming all the CPU
137 if (nwritten == -1 && errno == EAGAIN) {
142 FD_SET((unsigned)bsock->fd, &fdset);
145 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
149 return nwritten; /* error */
154 return nbytes - nleft;
158 * Receive a message from the other end. Each message consists of
159 * two packets. The first is a header that contains the size
160 * of the data that follows in the second packet.
161 * Returns number of bytes read (may return zero)
162 * Returns -1 on signal (BNET_SIGNAL)
163 * Returns -2 on hard end of file (BNET_HARDEOF)
164 * Returns -3 on error (BNET_ERROR)
166 * Unfortunately, it is a bit complicated because we have these
169 * 2. Signal including end of data stream
170 * 3. Hard end of file
172 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
174 int32_t bnet_recv(BSOCK * bsock)
179 ASSERT(bsock != NULL);
182 if (bsock->errors || bsock->terminated) {
186 bsock->read_seqno++; /* bump sequence number */
187 bsock->timer_start = watchdog_time; /* set start wait time */
188 bsock->timed_out = 0;
189 /* get data size -- in int32_t */
190 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
191 bsock->timer_start = 0; /* clear timer */
192 /* probably pipe broken because client died */
194 bsock->b_errno = ENODATA;
196 bsock->b_errno = errno;
199 return BNET_HARDEOF; /* assume hard EOF received */
201 bsock->timer_start = 0; /* clear timer */
202 if (nbytes != sizeof(int32_t)) {
204 bsock->b_errno = EIO;
205 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
206 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
210 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
212 if (pktsiz == 0) { /* No data transferred */
213 bsock->timer_start = 0; /* clear timer */
216 return 0; /* zero bytes read */
219 /* If signal or packet size too big */
220 if (pktsiz < 0 || pktsiz > 1000000) {
221 if (pktsiz > 0) { /* if packet too big */
222 Qmsg3(bsock->jcr, M_FATAL, 0,
223 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
224 bsock->who, bsock->host, bsock->port);
225 pktsiz = BNET_TERMINATE; /* hang up */
227 if (pktsiz == BNET_TERMINATE) {
228 bsock->terminated = 1;
230 bsock->timer_start = 0; /* clear timer */
231 bsock->b_errno = ENODATA;
232 bsock->msglen = pktsiz; /* signal code */
233 return BNET_SIGNAL; /* signal */
236 /* Make sure the buffer is big enough + one byte for EOS */
237 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
238 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
241 bsock->timer_start = watchdog_time; /* set start wait time */
242 bsock->timed_out = 0;
243 /* now read the actual data */
244 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
245 bsock->timer_start = 0; /* clear timer */
247 bsock->b_errno = ENODATA;
249 bsock->b_errno = errno;
252 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
253 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
256 bsock->timer_start = 0; /* clear timer */
258 bsock->msglen = nbytes;
259 if (nbytes != pktsiz) {
260 bsock->b_errno = EIO;
262 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
263 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
266 /* always add a zero by to properly terminate any
267 * string that was send to us. Note, we ensured above that the
268 * buffer is at least one byte longer than the message length.
270 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
271 sm_check(__FILE__, __LINE__, false);
272 return nbytes; /* return actual length of message */
277 * Return 1 if there are errors on this bsock or it is closed,
278 * i.e. stop communicating on this line.
280 bool is_bnet_stop(BSOCK * bsock)
282 return bsock->errors || bsock->terminated;
286 * Return number of errors on socket
288 int is_bnet_error(BSOCK * bsock)
290 errno = bsock->b_errno;
291 return bsock->errors;
295 * Call here after error during closing to suppress error
296 * messages which are due to the other end shutting down too.
298 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
300 bsock->suppress_error_msgs = flag;
305 * Transmit spooled data now to a BSOCK
307 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
312 ssize_t last = 0, size = 0;
315 rewind(bsock->spool_fd);
316 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
318 size += sizeof(int32_t);
319 bsock->msglen = ntohl(pktsiz);
320 if (bsock->msglen > 0) {
321 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
322 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
324 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
325 if (nbytes != (size_t) bsock->msglen) {
327 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
328 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
330 update_attr_spool_size(tsize - last);
334 if ((++count & 0x3F) == 0) {
335 update_attr_spool_size(size - last);
341 update_attr_spool_size(tsize - last);
342 if (ferror(bsock->spool_fd)) {
344 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
353 * Send a message over the network. The send consists of
354 * two network packets. The first is sends a 32 bit integer containing
355 * the length of the data packet which follows.
357 * Returns: false on failure
360 bool bnet_send(BSOCK * bsock)
365 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
368 pktsiz = htonl((int32_t) bsock->msglen);
369 /* send int32_t containing size of data packet */
370 bsock->timer_start = watchdog_time; /* start timer */
371 bsock->timed_out = 0;
372 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
373 bsock->timer_start = 0; /* clear timer */
374 if (rc != sizeof(int32_t)) {
375 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
376 bsock->terminated = 1;
377 return false; /* ignore any errors */
381 bsock->b_errno = EIO;
383 bsock->b_errno = errno;
386 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
387 Qmsg4(bsock->jcr, M_ERROR, 0,
388 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
389 bsock->host, bsock->port, bnet_strerror(bsock));
392 Qmsg5(bsock->jcr, M_ERROR, 0,
393 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who,
394 bsock->host, bsock->port, bsock->msglen, rc);
399 bsock->out_msg_no++; /* increment message number */
400 if (bsock->msglen <= 0) { /* length only? */
401 return true; /* yes, no data */
404 /* send data packet */
405 bsock->timer_start = watchdog_time; /* start timer */
406 bsock->timed_out = 0;
407 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
408 bsock->timer_start = 0; /* clear timer */
409 if (rc != bsock->msglen) {
412 bsock->b_errno = EIO;
414 bsock->b_errno = errno;
417 if (!bsock->suppress_error_msgs) {
418 Qmsg5(bsock->jcr, M_ERROR, 0,
419 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
420 bsock->msglen, bsock->who,
421 bsock->host, bsock->port, bnet_strerror(bsock));
424 Qmsg5(bsock->jcr, M_ERROR, 0,
425 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
426 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
434 * Establish a TLS connection -- server side
435 * Returns: 1 on success
439 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
443 tls = new_tls_connection(ctx, bsock->fd);
445 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
451 /* Initiate TLS Negotiation */
452 if (!tls_bsock_accept(bsock)) {
453 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
458 if (!tls_postconnect_verify_cn(tls, verify_list)) {
459 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
460 " Peer certificate did not match a required commonName\n"),
469 free_tls_connection(tls);
475 * Establish a TLS connection -- client side
476 * Returns: 1 on success
479 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
483 tls = new_tls_connection(ctx, bsock->fd);
485 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
491 /* Initiate TLS Negotiation */
492 if (!tls_bsock_connect(bsock)) {
496 if (!tls_postconnect_verify_host(tls, bsock->host)) {
497 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
504 free_tls_connection(tls);
508 #endif /* HAVE_TLS */
511 * Wait for a specified time for data to appear on
512 * the BSOCK connection.
514 * Returns: 1 if data available
518 int bnet_wait_data(BSOCK * bsock, int sec)
524 FD_SET((unsigned)bsock->fd, &fdset);
528 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
529 case 0: /* timeout */
533 bsock->b_errno = errno;
534 if (errno == EINTR || errno == EAGAIN) {
537 return -1; /* error return */
546 * As above, but returns on interrupt
548 int bnet_wait_data_intr(BSOCK * bsock, int sec)
554 FD_SET((unsigned)bsock->fd, &fdset);
558 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
559 case 0: /* timeout */
563 bsock->b_errno = errno;
564 return -1; /* error return */
572 #ifndef NETDB_INTERNAL
573 #define NETDB_INTERNAL -1 /* See errno. */
575 #ifndef NETDB_SUCCESS
576 #define NETDB_SUCCESS 0 /* No problem. */
578 #ifndef HOST_NOT_FOUND
579 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
582 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
585 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
588 #define NO_DATA 4 /* Valid name, no data record of requested type. */
592 * Get human readable error for gethostbyname()
594 static const char *gethost_strerror()
599 msg = strerror(errno);
605 msg = "Authoritative answer for host not found.";
608 msg = "Non-authoritative for host not found, or ServerFail.";
611 msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
614 msg = "Valid name, no data record of resquested type.";
617 msg = "Unknown error.";
625 static IPADDR *add_any(int family)
627 IPADDR *addr = New(IPADDR(family));
628 addr->set_type(IPADDR::R_MULTIPLE);
629 addr->set_addr_any();
633 static const char *resolv_host(int family, const char *host, dlist * addr_list)
639 #ifdef HAVE_GETHOSTBYNAME2
640 if ((hp = gethostbyname2(host, family)) == NULL) {
642 if ((hp = gethostbyname(host)) == NULL) {
644 /* may be the strerror give not the right result -:( */
645 errmsg = gethost_strerror();
650 for (p = hp->h_addr_list; *p != 0; p++) {
651 IPADDR *addr = New(IPADDR(hp->h_addrtype));
652 addr->set_type(IPADDR::R_MULTIPLE);
653 if (addr->get_family() == AF_INET) {
654 addr->set_addr4((struct in_addr*)*p);
658 addr->set_addr6((struct in6_addr*)*p);
661 addr_list->append(addr);
669 * i host = 0 mean INADDR_ANY only ipv4
671 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
673 struct in_addr inaddr;
677 struct in6_addr inaddr6;
680 dlist *addr_list = New(dlist(addr, &addr->link));
681 if (!host || host[0] == '\0') {
683 addr_list->append(add_any(family));
685 addr_list->append(add_any(AF_INET));
687 addr_list->append(add_any(AF_INET6));
690 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
691 addr = New(IPADDR(AF_INET));
692 addr->set_type(IPADDR::R_MULTIPLE);
693 addr->set_addr4(&inaddr);
694 addr_list->append(addr);
697 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
698 addr = New(IPADDR(AF_INET6));
699 addr->set_type(IPADDR::R_MULTIPLE);
700 addr->set_addr6(&inaddr6);
701 addr_list->append(addr);
706 errmsg = resolv_host(family, host, addr_list);
709 free_addresses(addr_list);
713 errmsg = resolv_host(AF_INET, host, addr_list);
716 errmsg = resolv_host(AF_INET6, host, addr_list);
721 free_addresses(addr_list);
730 * Open a TCP connection to the UPS network server
732 * Returns BSOCK * pointer on success
735 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
736 int port, int *fatal)
741 bool connected = false;
747 * Fill in the structure serv_addr with the address of
748 * the server that we want to connect with.
750 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
751 /* Note errstr is not malloc'ed */
752 Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
754 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
760 foreach_dlist(ipaddr, addr_list) {
761 ipaddr->set_port_net(htons(port));
762 char allbuf[256 * 10];
764 Dmsg2(100, "Current %sAll %s\n",
765 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
766 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
767 /* Open a TCP socket */
768 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
772 Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
773 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
777 * Keep socket from timing out from inactivity
779 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
781 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
784 /* connect to server */
785 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
796 free_addresses(addr_list);
801 * Keep socket from timing out from inactivity
802 * Do this a second time out of paranoia
804 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
806 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
809 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
810 free_addresses(addr_list);
815 * Try to connect to host for max_retry_time at retry_time intervals.
817 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
818 const char *name, char *host, char *service, int port,
825 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
826 i -= retry_interval) {
828 if (fatal || (jcr && job_canceled(jcr))) {
831 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
832 name, host, port, be.strerror());
834 i = 60 * 5; /* complain again in 5 minutes */
836 Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n"
837 "Retrying ...\n", name, host, port, be.strerror());
839 bmicrosleep(retry_interval, 0);
840 max_retry_time -= retry_interval;
841 if (max_retry_time <= 0) {
842 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
843 name, host, port, be.strerror());
852 * Return the string for the error that occurred
853 * on the socket. Only the first error is retained.
855 const char *bnet_strerror(BSOCK * bsock)
858 if (bsock->errmsg == NULL) {
859 bsock->errmsg = get_pool_memory(PM_MESSAGE);
861 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
862 return bsock->errmsg;
866 * Format and send a message
867 * Returns: false on error
870 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
875 if (bs->errors || bs->terminated) {
878 /* This probably won't work, but we vsnprintf, then if we
879 * get a negative length or a length greater than our buffer
880 * (depending on which library is used), the printf was truncated, so
881 * get a bigger buffer and try again.
884 maxlen = sizeof_pool_memory(bs->msg) - 1;
885 va_start(arg_ptr, fmt);
886 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
888 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
891 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
893 return bnet_send(bs);
897 * Set the network buffer size, suggested size is in size.
898 * Actual size obtained is returned in bs->msglen
900 * Returns: 0 on failure
903 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
905 uint32_t dbuf_size, start_size;
906 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
909 opt = IPTOS_THROUGHPUT;
910 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
916 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
918 start_size = dbuf_size;
919 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
920 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
923 if (rw & BNET_SETBUF_READ) {
924 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
925 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
927 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
928 dbuf_size -= TAPE_BSIZE;
930 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
931 if (dbuf_size != start_size) {
932 Qmsg1(bs->jcr, M_WARNING, 0,
933 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
935 if (dbuf_size % TAPE_BSIZE != 0) {
936 Qmsg1(bs->jcr, M_ABORT, 0,
937 _("Network buffer size %d not multiple of tape block size.\n"),
944 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
946 start_size = dbuf_size;
947 if (rw & BNET_SETBUF_WRITE) {
948 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
949 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
951 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
952 dbuf_size -= TAPE_BSIZE;
954 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
955 if (dbuf_size != start_size) {
956 Qmsg1(bs->jcr, M_WARNING, 0,
957 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
959 if (dbuf_size % TAPE_BSIZE != 0) {
960 Qmsg1(bs->jcr, M_ABORT, 0,
961 _("Network buffer size %d not multiple of tape block size.\n"),
966 bs->msglen = dbuf_size;
971 * Set socket non-blocking
972 * Returns previous socket flag
974 int bnet_set_nonblocking (BSOCK *bsock) {
978 /* Get current flags */
979 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
980 Emsg1(M_ABORT, 0, "fcntl F_GETFL error. ERR=%s\n", strerror(errno));
983 /* Set O_NONBLOCK flag */
984 if((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
985 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", strerror(errno));
994 flags = bsock->blocking;
995 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1003 * Set socket blocking
1004 * Returns previous socket flags
1006 int bnet_set_blocking (BSOCK *bsock) {
1009 /* Get current flags */
1010 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1011 Emsg1(M_ABORT, 0, "fcntl F_GETFL error. ERR=%s\n", strerror(errno));
1014 /* Set O_NONBLOCK flag */
1015 if((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1016 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", strerror(errno));
1019 bsock->blocking = 1;
1023 u_long ioctlArg = 0;
1025 flags = bsock->blocking;
1026 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1027 bsock->blocking = 1;
1034 * Restores socket flags
1036 void bnet_restore_blocking (BSOCK *bsock, int flags) {
1038 if((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1039 Emsg1(M_ABORT, 0, "fcntl F_SETFL error. ERR=%s\n", strerror(errno));
1042 bsock->blocking = (flags & O_NONBLOCK);
1044 u_long ioctlArg = flags;
1046 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1047 bsock->blocking = 1;
1053 * Send a network "signal" to the other end
1054 * This consists of sending a negative packet length
1056 * Returns: false on failure
1059 bool bnet_sig(BSOCK * bs, int sig)
1062 if (sig == BNET_TERMINATE) {
1063 bs->suppress_error_msgs = true;
1065 return bnet_send(bs);
1069 * Convert a network "signal" code into
1070 * human readable ASCII.
1072 const char *bnet_sig_to_ascii(BSOCK * bs)
1074 static char buf[30];
1075 switch (bs->msglen) {
1077 return "BNET_EOD"; /* end of data stream */
1079 return "BNET_EOD_POLL";
1081 return "BNET_STATUS";
1082 case BNET_TERMINATE:
1083 return "BNET_TERMINATE"; /* terminate connection */
1086 case BNET_HEARTBEAT:
1087 return "BNET_HEARTBEAT";
1088 case BNET_HB_RESPONSE:
1089 return "BNET_HB_RESPONSE";
1091 return "BNET_PROMPT";
1093 sprintf(buf, "Unknown sig %d", (int)bs->msglen);
1099 /* Initialize internal socket structure.
1100 * This probably should be done in net_open
1102 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1103 struct sockaddr *client_addr)
1105 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1106 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1107 memset(bsock, 0, sizeof(BSOCK));
1111 bsock->blocking = 1;
1112 bsock->msg = get_pool_memory(PM_MESSAGE);
1113 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1114 bsock->who = bstrdup(who);
1115 bsock->host = bstrdup(host);
1117 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1119 * ****FIXME**** reduce this to a few hours once
1120 * heartbeats are implemented
1122 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1127 BSOCK *dup_bsock(BSOCK * osock)
1129 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1130 memcpy(bsock, osock, sizeof(BSOCK));
1131 bsock->msg = get_pool_memory(PM_MESSAGE);
1132 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1134 bsock->who = bstrdup(osock->who);
1137 bsock->host = bstrdup(osock->host);
1139 bsock->duped = true;
1143 /* Close the network connection */
1144 void bnet_close(BSOCK * bsock)
1148 for (; bsock != NULL; bsock = next) {
1150 if (!bsock->duped) {
1152 /* Shutdown tls cleanly. */
1154 tls_bsock_shutdown(bsock);
1155 free_tls_connection(bsock->tls);
1158 #endif /* HAVE_TLS */
1159 if (bsock->timed_out) {
1160 shutdown(bsock->fd, 2); /* discard any pending I/O */
1162 socketClose(bsock->fd); /* normal close */
1169 void term_bsock(BSOCK * bsock)
1172 free_pool_memory(bsock->msg);
1175 ASSERT(1 == 0); /* double close */
1177 if (bsock->errmsg) {
1178 free_pool_memory(bsock->errmsg);
1179 bsock->errmsg = NULL;