2 * Network Utility Routines
6 * Adapted and enhanced for Bacula, originally written
7 * for inclusion in the Apcupsd package
12 Bacula® - The Network Backup Solution
14 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
16 The main author of Bacula is Kern Sibbald, with contributions from
17 many others, a complete list can be found in the file AUTHORS.
18 This program is Free Software; you can redistribute it and/or
19 modify it under the terms of version two of the GNU General Public
20 License as published by the Free Software Foundation plus additions
21 that are listed in the file LICENSE.
23 This program is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 Bacula® is a registered trademark of John Walker.
34 The licensor of Bacula is the Free Software Foundation Europe
35 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
36 Switzerland, email:ftf@fsfeurope.org.
44 extern time_t watchdog_time;
47 #define INADDR_NONE -1
50 #ifndef ENODATA /* not defined on BSD systems */
55 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
56 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
57 #define socketClose(fd) closesocket(fd)
59 #define socketRead(fd, buf, len) read(fd, buf, len)
60 #define socketWrite(fd, buf, len) write(fd, buf, len)
61 #define socketClose(fd) close(fd)
64 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
67 * Read a nbytes from the network.
68 * It is possible that the total bytes require in several
72 static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
79 return (tls_bsock_readn(bsock, ptr, nbytes));
86 nread = socketRead(bsock->fd, ptr, nleft);
87 if (bsock->timed_out || bsock->terminated) {
94 if (errno == EAGAIN) {
95 bmicrosleep(0, 200000); /* try again in 200ms */
100 return nread; /* error, or EOF */
105 return nbytes - nleft; /* return >= 0 */
109 * Write nbytes to the network.
110 * It may require several writes.
113 static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
115 int32_t nleft, nwritten;
118 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
119 if (nwritten != nbytes) {
121 bsock->b_errno = errno;
122 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
124 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
125 errno = bsock->b_errno;
134 return (tls_bsock_writen(bsock, ptr, nbytes));
136 #endif /* HAVE_TLS */
142 nwritten = socketWrite(bsock->fd, ptr, nleft);
143 if (bsock->timed_out || bsock->terminated) {
146 } while (nwritten == -1 && errno == EINTR);
148 * If connection is non-blocking, we will get EAGAIN, so
149 * use select() to keep from consuming all the CPU
152 if (nwritten == -1 && errno == EAGAIN) {
157 FD_SET((unsigned)bsock->fd, &fdset);
160 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
164 return nwritten; /* error */
169 return nbytes - nleft;
173 * Receive a message from the other end. Each message consists of
174 * two packets. The first is a header that contains the size
175 * of the data that follows in the second packet.
176 * Returns number of bytes read (may return zero)
177 * Returns -1 on signal (BNET_SIGNAL)
178 * Returns -2 on hard end of file (BNET_HARDEOF)
179 * Returns -3 on error (BNET_ERROR)
181 * Unfortunately, it is a bit complicated because we have these
184 * 2. Signal including end of data stream
185 * 3. Hard end of file
187 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
189 int32_t bnet_recv(BSOCK * bsock)
199 if (bsock->errors || bsock->terminated) {
203 bsock->read_seqno++; /* bump sequence number */
204 bsock->timer_start = watchdog_time; /* set start wait time */
205 bsock->timed_out = 0;
206 /* get data size -- in int32_t */
207 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
208 bsock->timer_start = 0; /* clear timer */
209 /* probably pipe broken because client died */
211 bsock->b_errno = ENODATA;
213 bsock->b_errno = errno;
216 return BNET_HARDEOF; /* assume hard EOF received */
218 bsock->timer_start = 0; /* clear timer */
219 if (nbytes != sizeof(int32_t)) {
221 bsock->b_errno = EIO;
222 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
223 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
227 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
229 if (pktsiz == 0) { /* No data transferred */
230 bsock->timer_start = 0; /* clear timer */
233 return 0; /* zero bytes read */
236 /* If signal or packet size too big */
237 if (pktsiz < 0 || pktsiz > 1000000) {
238 if (pktsiz > 0) { /* if packet too big */
239 Qmsg3(bsock->jcr, M_FATAL, 0,
240 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
241 bsock->who, bsock->host, bsock->port);
242 pktsiz = BNET_TERMINATE; /* hang up */
244 if (pktsiz == BNET_TERMINATE) {
245 bsock->terminated = 1;
247 bsock->timer_start = 0; /* clear timer */
248 bsock->b_errno = ENODATA;
249 bsock->msglen = pktsiz; /* signal code */
250 return BNET_SIGNAL; /* signal */
253 /* Make sure the buffer is big enough + one byte for EOS */
254 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
255 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
258 bsock->timer_start = watchdog_time; /* set start wait time */
259 bsock->timed_out = 0;
260 /* now read the actual data */
261 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
262 bsock->timer_start = 0; /* clear timer */
264 bsock->b_errno = ENODATA;
266 bsock->b_errno = errno;
269 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
270 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
273 bsock->timer_start = 0; /* clear timer */
275 bsock->msglen = nbytes;
276 if (nbytes != pktsiz) {
277 bsock->b_errno = EIO;
279 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
280 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
283 /* always add a zero by to properly terminate any
284 * string that was send to us. Note, we ensured above that the
285 * buffer is at least one byte longer than the message length.
287 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
288 sm_check(__FILE__, __LINE__, false);
289 return nbytes; /* return actual length of message */
294 * Return 1 if there are errors on this bsock or it is closed,
295 * i.e. stop communicating on this line.
297 bool is_bnet_stop(BSOCK * bsock)
299 return bsock->errors || bsock->terminated;
303 * Return number of errors on socket
305 int is_bnet_error(BSOCK * bsock)
307 errno = bsock->b_errno;
308 return bsock->errors;
312 * Call here after error during closing to suppress error
313 * messages which are due to the other end shutting down too.
315 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
317 bsock->suppress_error_msgs = flag;
322 * Transmit spooled data now to a BSOCK
324 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
329 ssize_t last = 0, size = 0;
332 rewind(bsock->spool_fd);
333 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
335 size += sizeof(int32_t);
336 bsock->msglen = ntohl(pktsiz);
337 if (bsock->msglen > 0) {
338 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
339 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
341 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
342 if (nbytes != (size_t) bsock->msglen) {
344 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
345 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
347 update_attr_spool_size(tsize - last);
351 if ((++count & 0x3F) == 0) {
352 update_attr_spool_size(size - last);
358 update_attr_spool_size(tsize - last);
359 if (ferror(bsock->spool_fd)) {
361 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
370 * Send a message over the network. The send consists of
371 * two network packets. The first is sends a 32 bit integer containing
372 * the length of the data packet which follows.
374 * Returns: false on failure
377 bool bnet_send(BSOCK * bsock)
382 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
385 pktsiz = htonl((int32_t) bsock->msglen);
386 /* send int32_t containing size of data packet */
387 bsock->timer_start = watchdog_time; /* start timer */
388 bsock->timed_out = 0;
389 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
390 bsock->timer_start = 0; /* clear timer */
391 if (rc != sizeof(int32_t)) {
392 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
393 bsock->terminated = 1;
394 return false; /* ignore any errors */
398 bsock->b_errno = EIO;
400 bsock->b_errno = errno;
403 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
404 Qmsg4(bsock->jcr, M_ERROR, 0,
405 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
406 bsock->host, bsock->port, bnet_strerror(bsock));
409 Qmsg5(bsock->jcr, M_ERROR, 0,
410 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
411 sizeof(int32_t), bsock->who,
412 bsock->host, bsock->port, rc);
417 bsock->out_msg_no++; /* increment message number */
418 if (bsock->msglen <= 0) { /* length only? */
419 return true; /* yes, no data */
422 /* send data packet */
423 bsock->timer_start = watchdog_time; /* start timer */
424 bsock->timed_out = 0;
425 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
426 bsock->timer_start = 0; /* clear timer */
427 if (rc != bsock->msglen) {
430 bsock->b_errno = EIO;
432 bsock->b_errno = errno;
435 if (!bsock->suppress_error_msgs) {
436 Qmsg5(bsock->jcr, M_ERROR, 0,
437 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
438 bsock->msglen, bsock->who,
439 bsock->host, bsock->port, bnet_strerror(bsock));
442 Qmsg5(bsock->jcr, M_ERROR, 0,
443 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
444 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
452 * Establish a TLS connection -- server side
453 * Returns: true on success
457 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
461 tls = new_tls_connection(ctx, bsock->fd);
463 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
469 /* Initiate TLS Negotiation */
470 if (!tls_bsock_accept(bsock)) {
471 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS Negotiation failed.\n"));
476 if (!tls_postconnect_verify_cn(tls, verify_list)) {
477 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
478 " Peer certificate did not match a required commonName\n"),
486 free_tls_connection(tls);
492 * Establish a TLS connection -- client side
493 * Returns: true on success
496 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
500 tls = new_tls_connection(ctx, bsock->fd);
502 Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n"));
508 /* Initiate TLS Negotiation */
509 if (!tls_bsock_connect(bsock)) {
513 if (!tls_postconnect_verify_host(tls, bsock->host)) {
514 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host);
520 free_tls_connection(tls);
525 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
527 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enabled but not configured.\n"));
530 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
532 Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enable but not configured.\n"));
535 #endif /* HAVE_TLS */
538 * Wait for a specified time for data to appear on
539 * the BSOCK connection.
541 * Returns: 1 if data available
545 int bnet_wait_data(BSOCK * bsock, int sec)
551 FD_SET((unsigned)bsock->fd, &fdset);
555 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
556 case 0: /* timeout */
560 bsock->b_errno = errno;
561 if (errno == EINTR) {
564 return -1; /* error return */
573 * As above, but returns on interrupt
575 int bnet_wait_data_intr(BSOCK * bsock, int sec)
581 FD_SET((unsigned)bsock->fd, &fdset);
584 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
585 case 0: /* timeout */
589 bsock->b_errno = errno;
590 return -1; /* error return */
597 #ifndef NETDB_INTERNAL
598 #define NETDB_INTERNAL -1 /* See errno. */
600 #ifndef NETDB_SUCCESS
601 #define NETDB_SUCCESS 0 /* No problem. */
603 #ifndef HOST_NOT_FOUND
604 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
607 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
610 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
613 #define NO_DATA 4 /* Valid name, no data record of requested type. */
617 * Get human readable error for gethostbyname()
619 static const char *gethost_strerror()
628 msg = _("No problem.");
631 msg = _("Authoritative answer for host not found.");
634 msg = _("Non-authoritative for host not found, or ServerFail.");
637 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
640 msg = _("Valid name, no data record of resquested type.");
643 msg = _("Unknown error.");
651 static IPADDR *add_any(int family)
653 IPADDR *addr = New(IPADDR(family));
654 addr->set_type(IPADDR::R_MULTIPLE);
655 addr->set_addr_any();
659 static const char *resolv_host(int family, const char *host, dlist * addr_list)
665 #ifdef HAVE_GETHOSTBYNAME2
666 if ((hp = gethostbyname2(host, family)) == NULL) {
668 if ((hp = gethostbyname(host)) == NULL) {
670 /* may be the strerror give not the right result -:( */
671 errmsg = gethost_strerror();
676 for (p = hp->h_addr_list; *p != 0; p++) {
677 IPADDR *addr = New(IPADDR(hp->h_addrtype));
678 addr->set_type(IPADDR::R_MULTIPLE);
679 if (addr->get_family() == AF_INET) {
680 addr->set_addr4((struct in_addr*)*p);
684 addr->set_addr6((struct in6_addr*)*p);
687 addr_list->append(addr);
695 * i host = 0 mean INADDR_ANY only ipv4
697 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
699 struct in_addr inaddr;
703 struct in6_addr inaddr6;
706 dlist *addr_list = New(dlist(addr, &addr->link));
707 if (!host || host[0] == '\0') {
709 addr_list->append(add_any(family));
711 addr_list->append(add_any(AF_INET));
713 addr_list->append(add_any(AF_INET6));
716 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
717 addr = New(IPADDR(AF_INET));
718 addr->set_type(IPADDR::R_MULTIPLE);
719 addr->set_addr4(&inaddr);
720 addr_list->append(addr);
723 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
724 addr = New(IPADDR(AF_INET6));
725 addr->set_type(IPADDR::R_MULTIPLE);
726 addr->set_addr6(&inaddr6);
727 addr_list->append(addr);
732 errmsg = resolv_host(family, host, addr_list);
735 free_addresses(addr_list);
739 errmsg = resolv_host(AF_INET, host, addr_list);
742 errmsg = resolv_host(AF_INET6, host, addr_list);
747 free_addresses(addr_list);
756 * Open a TCP connection to the UPS network server
758 * Returns BSOCK * pointer on success
761 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
762 int port, int *fatal)
767 bool connected = false;
773 * Fill in the structure serv_addr with the address of
774 * the server that we want to connect with.
776 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
777 /* Note errstr is not malloc'ed */
778 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
780 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
786 foreach_dlist(ipaddr, addr_list) {
787 ipaddr->set_port_net(htons(port));
788 char allbuf[256 * 10];
790 Dmsg2(100, "Current %sAll %s\n",
791 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
792 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
793 /* Open a TCP socket */
794 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
798 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
799 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
803 * Keep socket from timing out from inactivity
805 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
807 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
810 /* connect to server */
811 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
822 free_addresses(addr_list);
827 * Keep socket from timing out from inactivity
828 * Do this a second time out of paranoia
830 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
832 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
835 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
836 free_addresses(addr_list);
841 * Try to connect to host for max_retry_time at retry_time intervals.
843 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
844 const char *name, char *host, char *service, int port,
851 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
852 i -= retry_interval) {
854 if (fatal || (jcr && job_canceled(jcr))) {
857 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
858 name, host, port, be.strerror());
860 i = 60 * 5; /* complain again in 5 minutes */
862 Qmsg4(jcr, M_WARNING, 0, _(
863 "Could not connect to %s on %s:%d. ERR=%s\n"
864 "Retrying ...\n"), name, host, port, be.strerror());
866 bmicrosleep(retry_interval, 0);
867 max_retry_time -= retry_interval;
868 if (max_retry_time <= 0) {
869 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
870 name, host, port, be.strerror());
879 * Return the string for the error that occurred
880 * on the socket. Only the first error is retained.
882 const char *bnet_strerror(BSOCK * bsock)
885 if (bsock->errmsg == NULL) {
886 bsock->errmsg = get_pool_memory(PM_MESSAGE);
888 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
889 return bsock->errmsg;
893 * Format and send a message
894 * Returns: false on error
897 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
902 if (bs->errors || bs->terminated) {
905 /* This probably won't work, but we vsnprintf, then if we
906 * get a negative length or a length greater than our buffer
907 * (depending on which library is used), the printf was truncated, so
908 * get a bigger buffer and try again.
911 maxlen = sizeof_pool_memory(bs->msg) - 1;
912 va_start(arg_ptr, fmt);
913 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
915 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
918 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
920 return bnet_send(bs);
923 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
924 #if !defined(HAVE_WIN32)
925 if (bs->peer_addr.sin_family == 0) {
926 socklen_t salen = sizeof(bs->peer_addr);
927 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
928 if (rval < 0) return rval;
930 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
939 * Set the network buffer size, suggested size is in size.
940 * Actual size obtained is returned in bs->msglen
942 * Returns: 0 on failure
945 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
947 uint32_t dbuf_size, start_size;
948 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
951 opt = IPTOS_THROUGHPUT;
952 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
958 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
960 start_size = dbuf_size;
961 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
962 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
965 if (rw & BNET_SETBUF_READ) {
966 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
967 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
969 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
970 dbuf_size -= TAPE_BSIZE;
972 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
973 if (dbuf_size != start_size) {
974 Qmsg1(bs->jcr, M_WARNING, 0,
975 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
977 if (dbuf_size % TAPE_BSIZE != 0) {
978 Qmsg1(bs->jcr, M_ABORT, 0,
979 _("Network buffer size %d not multiple of tape block size.\n"),
986 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
988 start_size = dbuf_size;
989 if (rw & BNET_SETBUF_WRITE) {
990 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
991 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
993 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
994 dbuf_size -= TAPE_BSIZE;
996 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
997 if (dbuf_size != start_size) {
998 Qmsg1(bs->jcr, M_WARNING, 0,
999 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
1001 if (dbuf_size % TAPE_BSIZE != 0) {
1002 Qmsg1(bs->jcr, M_ABORT, 0,
1003 _("Network buffer size %d not multiple of tape block size.\n"),
1008 bs->msglen = dbuf_size;
1013 * Set socket non-blocking
1014 * Returns previous socket flag
1016 int bnet_set_nonblocking (BSOCK *bsock) {
1020 /* Get current flags */
1021 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1023 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1026 /* Set O_NONBLOCK flag */
1027 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
1029 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1032 bsock->blocking = 0;
1036 u_long ioctlArg = 1;
1038 flags = bsock->blocking;
1039 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1040 bsock->blocking = 0;
1047 * Set socket blocking
1048 * Returns previous socket flags
1050 int bnet_set_blocking (BSOCK *bsock)
1054 /* Get current flags */
1055 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
1057 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
1060 /* Set O_NONBLOCK flag */
1061 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
1063 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1066 bsock->blocking = 1;
1070 u_long ioctlArg = 0;
1072 flags = bsock->blocking;
1073 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1074 bsock->blocking = 1;
1081 * Restores socket flags
1083 void bnet_restore_blocking (BSOCK *bsock, int flags)
1086 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1088 Jmsg1(bsock->jcr, M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1091 bsock->blocking = (flags & O_NONBLOCK);
1093 u_long ioctlArg = flags;
1095 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1096 bsock->blocking = 1;
1102 * Send a network "signal" to the other end
1103 * This consists of sending a negative packet length
1105 * Returns: false on failure
1108 bool bnet_sig(BSOCK * bs, int sig)
1111 if (sig == BNET_TERMINATE) {
1112 bs->suppress_error_msgs = true;
1114 return bnet_send(bs);
1118 * Convert a network "signal" code into
1119 * human readable ASCII.
1121 const char *bnet_sig_to_ascii(BSOCK * bs)
1123 static char buf[30];
1124 switch (bs->msglen) {
1126 return "BNET_EOD"; /* end of data stream */
1128 return "BNET_EOD_POLL";
1130 return "BNET_STATUS";
1131 case BNET_TERMINATE:
1132 return "BNET_TERMINATE"; /* terminate connection */
1135 case BNET_HEARTBEAT:
1136 return "BNET_HEARTBEAT";
1137 case BNET_HB_RESPONSE:
1138 return "BNET_HB_RESPONSE";
1140 return "BNET_PROMPT";
1142 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1148 /* Initialize internal socket structure.
1149 * This probably should be done in net_open
1151 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1152 struct sockaddr *client_addr)
1154 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1155 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1156 memset(bsock, 0, sizeof(BSOCK));
1160 bsock->blocking = 1;
1161 bsock->msg = get_pool_memory(PM_MESSAGE);
1162 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1163 bsock->who = bstrdup(who);
1164 bsock->host = bstrdup(host);
1166 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1167 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1169 * ****FIXME**** reduce this to a few hours once
1170 * heartbeats are implemented
1172 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1177 BSOCK *dup_bsock(BSOCK * osock)
1179 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
1180 memcpy(bsock, osock, sizeof(BSOCK));
1181 bsock->msg = get_pool_memory(PM_MESSAGE);
1182 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1184 bsock->who = bstrdup(osock->who);
1187 bsock->host = bstrdup(osock->host);
1189 bsock->duped = true;
1193 /* Close the network connection */
1194 void bnet_close(BSOCK * bsock)
1198 for (; bsock != NULL; bsock = next) {
1200 if (!bsock->duped) {
1202 /* Shutdown tls cleanly. */
1204 tls_bsock_shutdown(bsock);
1205 free_tls_connection(bsock->tls);
1208 #endif /* HAVE_TLS */
1209 if (bsock->timed_out) {
1210 shutdown(bsock->fd, 2); /* discard any pending I/O */
1212 socketClose(bsock->fd); /* normal close */
1219 void term_bsock(BSOCK * bsock)
1222 free_pool_memory(bsock->msg);
1225 ASSERT(1 == 0); /* double close */
1227 if (bsock->errmsg) {
1228 free_pool_memory(bsock->errmsg);
1229 bsock->errmsg = NULL;