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));
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()
607 msg = _("No problem.");
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, _(
842 "Could not connect to %s on %s:%d. ERR=%s\n"
843 "Retrying ...\n"), name, host, port, be.strerror());
845 bmicrosleep(retry_interval, 0);
846 max_retry_time -= retry_interval;
847 if (max_retry_time <= 0) {
848 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
849 name, host, port, be.strerror());
858 * Return the string for the error that occurred
859 * on the socket. Only the first error is retained.
861 const char *bnet_strerror(BSOCK * bsock)
864 if (bsock->errmsg == NULL) {
865 bsock->errmsg = get_pool_memory(PM_MESSAGE);
867 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
868 return bsock->errmsg;
872 * Format and send a message
873 * Returns: false on error
876 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
881 if (bs->errors || bs->terminated) {
884 /* This probably won't work, but we vsnprintf, then if we
885 * get a negative length or a length greater than our buffer
886 * (depending on which library is used), the printf was truncated, so
887 * get a bigger buffer and try again.
890 maxlen = sizeof_pool_memory(bs->msg) - 1;
891 va_start(arg_ptr, fmt);
892 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
894 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
897 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
899 return bnet_send(bs);
903 * Set the network buffer size, suggested size is in size.
904 * Actual size obtained is returned in bs->msglen
906 * Returns: 0 on failure
909 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
911 uint32_t dbuf_size, start_size;
912 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
915 opt = IPTOS_THROUGHPUT;
916 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
922 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
924 start_size = dbuf_size;
925 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
926 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
929 if (rw & BNET_SETBUF_READ) {
930 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
931 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
933 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
934 dbuf_size -= TAPE_BSIZE;
936 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
937 if (dbuf_size != start_size) {
938 Qmsg1(bs->jcr, M_WARNING, 0,
939 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
941 if (dbuf_size % TAPE_BSIZE != 0) {
942 Qmsg1(bs->jcr, M_ABORT, 0,
943 _("Network buffer size %d not multiple of tape block size.\n"),
950 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
952 start_size = dbuf_size;
953 if (rw & BNET_SETBUF_WRITE) {
954 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
955 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
957 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
958 dbuf_size -= TAPE_BSIZE;
960 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
961 if (dbuf_size != start_size) {
962 Qmsg1(bs->jcr, M_WARNING, 0,
963 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
965 if (dbuf_size % TAPE_BSIZE != 0) {
966 Qmsg1(bs->jcr, M_ABORT, 0,
967 _("Network buffer size %d not multiple of tape block size.\n"),
972 bs->msglen = dbuf_size;
977 * Set socket non-blocking
978 * Returns previous socket flag
980 int bnet_set_nonblocking (BSOCK *bsock) {
984 /* Get current flags */
985 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
987 Emsg1(M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
990 /* Set O_NONBLOCK flag */
991 if((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
993 Emsg1(M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1000 u_long ioctlArg = 1;
1002 flags = bsock->blocking;
1003 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1004 bsock->blocking = 0;
1011 * Set socket blocking
1012 * Returns previous socket flags
1014 int bnet_set_blocking (BSOCK *bsock) {
1017 /* Get current flags */
1018 if((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1020 Emsg1(M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1023 /* Set O_NONBLOCK flag */
1024 if((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1026 Emsg1(M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1029 bsock->blocking = 1;
1033 u_long ioctlArg = 0;
1035 flags = bsock->blocking;
1036 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1037 bsock->blocking = 1;
1044 * Restores socket flags
1046 void bnet_restore_blocking (BSOCK *bsock, int flags) {
1048 if((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1050 Emsg1(M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1053 bsock->blocking = (flags & O_NONBLOCK);
1055 u_long ioctlArg = flags;
1057 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1058 bsock->blocking = 1;
1064 * Send a network "signal" to the other end
1065 * This consists of sending a negative packet length
1067 * Returns: false on failure
1070 bool bnet_sig(BSOCK * bs, int sig)
1073 if (sig == BNET_TERMINATE) {
1074 bs->suppress_error_msgs = true;
1076 return bnet_send(bs);
1080 * Convert a network "signal" code into
1081 * human readable ASCII.
1083 const char *bnet_sig_to_ascii(BSOCK * bs)
1085 static char buf[30];
1086 switch (bs->msglen) {
1088 return "BNET_EOD"; /* end of data stream */
1090 return "BNET_EOD_POLL";
1092 return "BNET_STATUS";
1093 case BNET_TERMINATE:
1094 return "BNET_TERMINATE"; /* terminate connection */
1097 case BNET_HEARTBEAT:
1098 return "BNET_HEARTBEAT";
1099 case BNET_HB_RESPONSE:
1100 return "BNET_HB_RESPONSE";
1102 return "BNET_PROMPT";
1104 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1110 /* Initialize internal socket structure.
1111 * This probably should be done in net_open
1113 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1114 struct sockaddr *client_addr)
1116 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1117 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1118 memset(bsock, 0, sizeof(BSOCK));
1122 bsock->blocking = 1;
1123 bsock->msg = get_pool_memory(PM_MESSAGE);
1124 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1125 bsock->who = bstrdup(who);
1126 bsock->host = bstrdup(host);
1128 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1130 * ****FIXME**** reduce this to a few hours once
1131 * heartbeats are implemented
1133 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1138 BSOCK *dup_bsock(BSOCK * osock)
1140 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1141 memcpy(bsock, osock, sizeof(BSOCK));
1142 bsock->msg = get_pool_memory(PM_MESSAGE);
1143 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1145 bsock->who = bstrdup(osock->who);
1148 bsock->host = bstrdup(osock->host);
1150 bsock->duped = true;
1154 /* Close the network connection */
1155 void bnet_close(BSOCK * bsock)
1159 for (; bsock != NULL; bsock = next) {
1161 if (!bsock->duped) {
1163 /* Shutdown tls cleanly. */
1165 tls_bsock_shutdown(bsock);
1166 free_tls_connection(bsock->tls);
1169 #endif /* HAVE_TLS */
1170 if (bsock->timed_out) {
1171 shutdown(bsock->fd, 2); /* discard any pending I/O */
1173 socketClose(bsock->fd); /* normal close */
1180 void term_bsock(BSOCK * bsock)
1183 free_pool_memory(bsock->msg);
1186 ASSERT(1 == 0); /* double close */
1188 if (bsock->errmsg) {
1189 free_pool_memory(bsock->errmsg);
1190 bsock->errmsg = NULL;