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)
181 ASSERT(bsock != NULL);
184 if (bsock->errors || bsock->terminated) {
188 bsock->read_seqno++; /* bump sequence number */
189 bsock->timer_start = watchdog_time; /* set start wait time */
190 bsock->timed_out = 0;
191 /* get data size -- in int32_t */
192 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
193 bsock->timer_start = 0; /* clear timer */
194 /* probably pipe broken because client died */
196 bsock->b_errno = ENODATA;
198 bsock->b_errno = errno;
201 return BNET_HARDEOF; /* assume hard EOF received */
203 bsock->timer_start = 0; /* clear timer */
204 if (nbytes != sizeof(int32_t)) {
206 bsock->b_errno = EIO;
207 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
208 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
212 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
214 if (pktsiz == 0) { /* No data transferred */
215 bsock->timer_start = 0; /* clear timer */
218 return 0; /* zero bytes read */
221 /* If signal or packet size too big */
222 if (pktsiz < 0 || pktsiz > 1000000) {
223 if (pktsiz > 0) { /* if packet too big */
224 Qmsg3(bsock->jcr, M_FATAL, 0,
225 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
226 bsock->who, bsock->host, bsock->port);
227 pktsiz = BNET_TERMINATE; /* hang up */
229 if (pktsiz == BNET_TERMINATE) {
230 bsock->terminated = 1;
232 bsock->timer_start = 0; /* clear timer */
233 bsock->b_errno = ENODATA;
234 bsock->msglen = pktsiz; /* signal code */
235 return BNET_SIGNAL; /* signal */
238 /* Make sure the buffer is big enough + one byte for EOS */
239 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
240 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
243 bsock->timer_start = watchdog_time; /* set start wait time */
244 bsock->timed_out = 0;
245 /* now read the actual data */
246 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
247 bsock->timer_start = 0; /* clear timer */
249 bsock->b_errno = ENODATA;
251 bsock->b_errno = errno;
254 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
255 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
258 bsock->timer_start = 0; /* clear timer */
260 bsock->msglen = nbytes;
261 if (nbytes != pktsiz) {
262 bsock->b_errno = EIO;
264 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
265 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
268 /* always add a zero by to properly terminate any
269 * string that was send to us. Note, we ensured above that the
270 * buffer is at least one byte longer than the message length.
272 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
273 sm_check(__FILE__, __LINE__, false);
274 return nbytes; /* return actual length of message */
279 * Return 1 if there are errors on this bsock or it is closed,
280 * i.e. stop communicating on this line.
282 bool is_bnet_stop(BSOCK * bsock)
284 return bsock->errors || bsock->terminated;
288 * Return number of errors on socket
290 int is_bnet_error(BSOCK * bsock)
292 errno = bsock->b_errno;
293 return bsock->errors;
297 * Call here after error during closing to suppress error
298 * messages which are due to the other end shutting down too.
300 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
302 bsock->suppress_error_msgs = flag;
307 * Transmit spooled data now to a BSOCK
309 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
314 ssize_t last = 0, size = 0;
317 rewind(bsock->spool_fd);
318 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
320 size += sizeof(int32_t);
321 bsock->msglen = ntohl(pktsiz);
322 if (bsock->msglen > 0) {
323 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
324 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
326 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
327 if (nbytes != (size_t) bsock->msglen) {
329 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
330 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
332 update_attr_spool_size(tsize - last);
336 if ((++count & 0x3F) == 0) {
337 update_attr_spool_size(size - last);
343 update_attr_spool_size(tsize - last);
344 if (ferror(bsock->spool_fd)) {
346 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
355 * Send a message over the network. The send consists of
356 * two network packets. The first is sends a 32 bit integer containing
357 * the length of the data packet which follows.
359 * Returns: false on failure
362 bool bnet_send(BSOCK * bsock)
367 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
370 pktsiz = htonl((int32_t) bsock->msglen);
371 /* send int32_t containing size of data packet */
372 bsock->timer_start = watchdog_time; /* start timer */
373 bsock->timed_out = 0;
374 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
375 bsock->timer_start = 0; /* clear timer */
376 if (rc != sizeof(int32_t)) {
377 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
378 bsock->terminated = 1;
379 return false; /* ignore any errors */
383 bsock->b_errno = EIO;
385 bsock->b_errno = errno;
388 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
389 Qmsg4(bsock->jcr, M_ERROR, 0,
390 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
391 bsock->host, bsock->port, bnet_strerror(bsock));
394 Qmsg5(bsock->jcr, M_ERROR, 0,
395 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who,
396 bsock->host, bsock->port, bsock->msglen, rc);
401 bsock->out_msg_no++; /* increment message number */
402 if (bsock->msglen <= 0) { /* length only? */
403 return true; /* yes, no data */
406 /* send data packet */
407 bsock->timer_start = watchdog_time; /* start timer */
408 bsock->timed_out = 0;
409 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
410 bsock->timer_start = 0; /* clear timer */
411 if (rc != bsock->msglen) {
414 bsock->b_errno = EIO;
416 bsock->b_errno = errno;
419 if (!bsock->suppress_error_msgs) {
420 Qmsg5(bsock->jcr, M_ERROR, 0,
421 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
422 bsock->msglen, bsock->who,
423 bsock->host, bsock->port, bnet_strerror(bsock));
426 Qmsg5(bsock->jcr, M_ERROR, 0,
427 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
428 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
436 * Establish a TLS connection -- server side
437 * Returns: 1 on success
441 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
445 tls = new_tls_connection(ctx, bsock->fd);
447 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
453 /* Initiate TLS Negotiation */
454 if (!tls_bsock_accept(bsock)) {
455 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
460 if (!tls_postconnect_verify_cn(tls, verify_list)) {
461 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
462 " Peer certificate did not match a required commonName\n"),
471 free_tls_connection(tls);
477 * Establish a TLS connection -- client side
478 * Returns: 1 on success
481 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
485 tls = new_tls_connection(ctx, bsock->fd);
487 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
493 /* Initiate TLS Negotiation */
494 if (!tls_bsock_connect(bsock)) {
498 if (!tls_postconnect_verify_host(tls, bsock->host)) {
499 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
506 free_tls_connection(tls);
511 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
513 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
516 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
518 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n"));
521 #endif /* HAVE_TLS */
524 * Wait for a specified time for data to appear on
525 * the BSOCK connection.
527 * Returns: 1 if data available
531 int bnet_wait_data(BSOCK * bsock, int sec)
537 FD_SET((unsigned)bsock->fd, &fdset);
541 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
542 case 0: /* timeout */
546 bsock->b_errno = errno;
547 if (errno == EINTR) {
550 return -1; /* error return */
559 * As above, but returns on interrupt
561 int bnet_wait_data_intr(BSOCK * bsock, int sec)
567 FD_SET((unsigned)bsock->fd, &fdset);
570 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
571 case 0: /* timeout */
575 bsock->b_errno = errno;
576 return -1; /* error return */
583 #ifndef NETDB_INTERNAL
584 #define NETDB_INTERNAL -1 /* See errno. */
586 #ifndef NETDB_SUCCESS
587 #define NETDB_SUCCESS 0 /* No problem. */
589 #ifndef HOST_NOT_FOUND
590 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
593 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
596 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
599 #define NO_DATA 4 /* Valid name, no data record of requested type. */
603 * Get human readable error for gethostbyname()
605 static const char *gethost_strerror()
614 msg = _("No problem.");
617 msg = _("Authoritative answer for host not found.");
620 msg = _("Non-authoritative for host not found, or ServerFail.");
623 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
626 msg = _("Valid name, no data record of resquested type.");
629 msg = _("Unknown error.");
637 static IPADDR *add_any(int family)
639 IPADDR *addr = New(IPADDR(family));
640 addr->set_type(IPADDR::R_MULTIPLE);
641 addr->set_addr_any();
645 static const char *resolv_host(int family, const char *host, dlist * addr_list)
651 #ifdef HAVE_GETHOSTBYNAME2
652 if ((hp = gethostbyname2(host, family)) == NULL) {
654 if ((hp = gethostbyname(host)) == NULL) {
656 /* may be the strerror give not the right result -:( */
657 errmsg = gethost_strerror();
662 for (p = hp->h_addr_list; *p != 0; p++) {
663 IPADDR *addr = New(IPADDR(hp->h_addrtype));
664 addr->set_type(IPADDR::R_MULTIPLE);
665 if (addr->get_family() == AF_INET) {
666 addr->set_addr4((struct in_addr*)*p);
670 addr->set_addr6((struct in6_addr*)*p);
673 addr_list->append(addr);
681 * i host = 0 mean INADDR_ANY only ipv4
683 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
685 struct in_addr inaddr;
689 struct in6_addr inaddr6;
692 dlist *addr_list = New(dlist(addr, &addr->link));
693 if (!host || host[0] == '\0') {
695 addr_list->append(add_any(family));
697 addr_list->append(add_any(AF_INET));
699 addr_list->append(add_any(AF_INET6));
702 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
703 addr = New(IPADDR(AF_INET));
704 addr->set_type(IPADDR::R_MULTIPLE);
705 addr->set_addr4(&inaddr);
706 addr_list->append(addr);
709 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
710 addr = New(IPADDR(AF_INET6));
711 addr->set_type(IPADDR::R_MULTIPLE);
712 addr->set_addr6(&inaddr6);
713 addr_list->append(addr);
718 errmsg = resolv_host(family, host, addr_list);
721 free_addresses(addr_list);
725 errmsg = resolv_host(AF_INET, host, addr_list);
728 errmsg = resolv_host(AF_INET6, host, addr_list);
733 free_addresses(addr_list);
742 * Open a TCP connection to the UPS network server
744 * Returns BSOCK * pointer on success
747 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
748 int port, int *fatal)
753 bool connected = false;
759 * Fill in the structure serv_addr with the address of
760 * the server that we want to connect with.
762 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
763 /* Note errstr is not malloc'ed */
764 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
766 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
772 foreach_dlist(ipaddr, addr_list) {
773 ipaddr->set_port_net(htons(port));
774 char allbuf[256 * 10];
776 Dmsg2(100, "Current %sAll %s\n",
777 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
778 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
779 /* Open a TCP socket */
780 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
784 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
785 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
789 * Keep socket from timing out from inactivity
791 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
793 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
796 /* connect to server */
797 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
808 free_addresses(addr_list);
813 * Keep socket from timing out from inactivity
814 * Do this a second time out of paranoia
816 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
818 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
821 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
822 free_addresses(addr_list);
827 * Try to connect to host for max_retry_time at retry_time intervals.
829 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
830 const char *name, char *host, char *service, int port,
837 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
838 i -= retry_interval) {
840 if (fatal || (jcr && job_canceled(jcr))) {
843 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
844 name, host, port, be.strerror());
846 i = 60 * 5; /* complain again in 5 minutes */
848 Qmsg4(jcr, M_WARNING, 0, _(
849 "Could not connect to %s on %s:%d. ERR=%s\n"
850 "Retrying ...\n"), name, host, port, be.strerror());
852 bmicrosleep(retry_interval, 0);
853 max_retry_time -= retry_interval;
854 if (max_retry_time <= 0) {
855 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
856 name, host, port, be.strerror());
865 * Return the string for the error that occurred
866 * on the socket. Only the first error is retained.
868 const char *bnet_strerror(BSOCK * bsock)
871 if (bsock->errmsg == NULL) {
872 bsock->errmsg = get_pool_memory(PM_MESSAGE);
874 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
875 return bsock->errmsg;
879 * Format and send a message
880 * Returns: false on error
883 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
888 if (bs->errors || bs->terminated) {
891 /* This probably won't work, but we vsnprintf, then if we
892 * get a negative length or a length greater than our buffer
893 * (depending on which library is used), the printf was truncated, so
894 * get a bigger buffer and try again.
897 maxlen = sizeof_pool_memory(bs->msg) - 1;
898 va_start(arg_ptr, fmt);
899 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
901 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
904 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
906 return bnet_send(bs);
910 * Set the network buffer size, suggested size is in size.
911 * Actual size obtained is returned in bs->msglen
913 * Returns: 0 on failure
916 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
918 uint32_t dbuf_size, start_size;
919 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
922 opt = IPTOS_THROUGHPUT;
923 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
929 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
931 start_size = dbuf_size;
932 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
933 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
936 if (rw & BNET_SETBUF_READ) {
937 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
938 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
940 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
941 dbuf_size -= TAPE_BSIZE;
943 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
944 if (dbuf_size != start_size) {
945 Qmsg1(bs->jcr, M_WARNING, 0,
946 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
948 if (dbuf_size % TAPE_BSIZE != 0) {
949 Qmsg1(bs->jcr, M_ABORT, 0,
950 _("Network buffer size %d not multiple of tape block size.\n"),
957 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
959 start_size = dbuf_size;
960 if (rw & BNET_SETBUF_WRITE) {
961 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
962 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
964 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
965 dbuf_size -= TAPE_BSIZE;
967 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
968 if (dbuf_size != start_size) {
969 Qmsg1(bs->jcr, M_WARNING, 0,
970 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
972 if (dbuf_size % TAPE_BSIZE != 0) {
973 Qmsg1(bs->jcr, M_ABORT, 0,
974 _("Network buffer size %d not multiple of tape block size.\n"),
979 bs->msglen = dbuf_size;
984 * Set socket non-blocking
985 * Returns previous socket flag
987 int bnet_set_nonblocking (BSOCK *bsock) {
991 /* Get current flags */
992 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
994 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
997 /* Set O_NONBLOCK flag */
998 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
1000 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1003 bsock->blocking = 0;
1007 u_long ioctlArg = 1;
1009 flags = bsock->blocking;
1010 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1011 bsock->blocking = 0;
1018 * Set socket blocking
1019 * Returns previous socket flags
1021 int bnet_set_blocking (BSOCK *bsock)
1025 /* Get current flags */
1026 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1028 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1031 /* Set O_NONBLOCK flag */
1032 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1034 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1037 bsock->blocking = 1;
1041 u_long ioctlArg = 0;
1043 flags = bsock->blocking;
1044 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1045 bsock->blocking = 1;
1052 * Restores socket flags
1054 void bnet_restore_blocking (BSOCK *bsock, int flags)
1057 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1059 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1062 bsock->blocking = (flags & O_NONBLOCK);
1064 u_long ioctlArg = flags;
1066 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1067 bsock->blocking = 1;
1073 * Send a network "signal" to the other end
1074 * This consists of sending a negative packet length
1076 * Returns: false on failure
1079 bool bnet_sig(BSOCK * bs, int sig)
1082 if (sig == BNET_TERMINATE) {
1083 bs->suppress_error_msgs = true;
1085 return bnet_send(bs);
1089 * Convert a network "signal" code into
1090 * human readable ASCII.
1092 const char *bnet_sig_to_ascii(BSOCK * bs)
1094 static char buf[30];
1095 switch (bs->msglen) {
1097 return "BNET_EOD"; /* end of data stream */
1099 return "BNET_EOD_POLL";
1101 return "BNET_STATUS";
1102 case BNET_TERMINATE:
1103 return "BNET_TERMINATE"; /* terminate connection */
1106 case BNET_HEARTBEAT:
1107 return "BNET_HEARTBEAT";
1108 case BNET_HB_RESPONSE:
1109 return "BNET_HB_RESPONSE";
1111 return "BNET_PROMPT";
1113 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1119 /* Initialize internal socket structure.
1120 * This probably should be done in net_open
1122 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1123 struct sockaddr *client_addr)
1125 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1126 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1127 memset(bsock, 0, sizeof(BSOCK));
1131 bsock->blocking = 1;
1132 bsock->msg = get_pool_memory(PM_MESSAGE);
1133 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1134 bsock->who = bstrdup(who);
1135 bsock->host = bstrdup(host);
1137 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1139 * ****FIXME**** reduce this to a few hours once
1140 * heartbeats are implemented
1142 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1147 BSOCK *dup_bsock(BSOCK * osock)
1149 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1150 memcpy(bsock, osock, sizeof(BSOCK));
1151 bsock->msg = get_pool_memory(PM_MESSAGE);
1152 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1154 bsock->who = bstrdup(osock->who);
1157 bsock->host = bstrdup(osock->host);
1159 bsock->duped = true;
1163 /* Close the network connection */
1164 void bnet_close(BSOCK * bsock)
1168 for (; bsock != NULL; bsock = next) {
1170 if (!bsock->duped) {
1172 /* Shutdown tls cleanly. */
1174 tls_bsock_shutdown(bsock);
1175 free_tls_connection(bsock->tls);
1178 #endif /* HAVE_TLS */
1179 if (bsock->timed_out) {
1180 shutdown(bsock->fd, 2); /* discard any pending I/O */
1182 socketClose(bsock->fd); /* normal close */
1189 void term_bsock(BSOCK * bsock)
1192 free_pool_memory(bsock->msg);
1195 ASSERT(1 == 0); /* double close */
1197 if (bsock->errmsg) {
1198 free_pool_memory(bsock->errmsg);
1199 bsock->errmsg = NULL;