2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation plus additions
11 that are listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Network Utility Routines
33 * Adapted and enhanced for Bacula, originally written
34 * for inclusion in the Apcupsd package
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 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 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)
191 return bsock->recv();
196 * Return 1 if there are errors on this bsock or it is closed,
197 * i.e. stop communicating on this line.
199 bool is_bnet_stop(BSOCK * bsock)
201 return bsock->errors || bsock->terminated;
205 * Return number of errors on socket
207 int is_bnet_error(BSOCK * bsock)
209 errno = bsock->b_errno;
210 return bsock->errors;
214 * Call here after error during closing to suppress error
215 * messages which are due to the other end shutting down too.
217 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
219 bsock->suppress_error_msgs = flag;
224 * Transmit spooled data now to a BSOCK
226 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
231 ssize_t last = 0, size = 0;
234 rewind(bsock->spool_fd);
235 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
237 size += sizeof(int32_t);
238 bsock->msglen = ntohl(pktsiz);
239 if (bsock->msglen > 0) {
240 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
241 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
243 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
244 if (nbytes != (size_t) bsock->msglen) {
246 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
247 Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
249 update_attr_spool_size(tsize - last);
253 if ((++count & 0x3F) == 0) {
254 update_attr_spool_size(size - last);
260 update_attr_spool_size(tsize - last);
261 if (ferror(bsock->spool_fd)) {
263 Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
272 * Send a message over the network. The send consists of
273 * two network packets. The first is sends a 32 bit integer containing
274 * the length of the data packet which follows.
276 * Returns: false on failure
279 bool bnet_send(BSOCK *bsock)
281 return bsock->send();
285 bool bnet_send(BSOCK * bsock)
290 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
293 pktsiz = htonl((int32_t)bsock->msglen);
294 /* send int32_t containing size of data packet */
295 bsock->timer_start = watchdog_time; /* start timer */
296 bsock->timed_out = 0;
297 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
298 bsock->timer_start = 0; /* clear timer */
299 if (rc != sizeof(int32_t)) {
300 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
301 bsock->terminated = 1;
302 return false; /* ignore any errors */
306 bsock->b_errno = EIO;
308 bsock->b_errno = errno;
311 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
312 Qmsg4(bsock->jcr(), M_ERROR, 0,
313 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
314 bsock->host(), bsock->port(), bnet_strerror(bsock));
317 Qmsg5(bsock->jcr(), M_ERROR, 0,
318 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
319 sizeof(int32_t), bsock->who(),
320 bsock->host(), bsock->port(), rc);
325 bsock->out_msg_no++; /* increment message number */
326 if (bsock->msglen <= 0) { /* length only? */
327 return true; /* yes, no data */
330 /* send data packet */
331 bsock->timer_start = watchdog_time; /* start timer */
332 bsock->timed_out = 0;
333 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
334 bsock->timer_start = 0; /* clear timer */
335 if (rc != bsock->msglen) {
338 bsock->b_errno = EIO;
340 bsock->b_errno = errno;
343 if (!bsock->suppress_error_msgs) {
344 Qmsg5(bsock->jcr(), M_ERROR, 0,
345 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
346 bsock->msglen, bsock->who(),
347 bsock->host(), bsock->port(), bnet_strerror(bsock));
350 Qmsg5(bsock->jcr(), M_ERROR, 0,
351 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
352 bsock->msglen, bsock->who(), bsock->host(),
362 * Establish a TLS connection -- server side
363 * Returns: true on success
367 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
371 tls = new_tls_connection(ctx, bsock->fd);
373 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
379 /* Initiate TLS Negotiation */
380 if (!tls_bsock_accept(bsock)) {
381 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
386 if (!tls_postconnect_verify_cn(tls, verify_list)) {
387 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
388 " Peer certificate did not match a required commonName\n"),
396 free_tls_connection(tls);
402 * Establish a TLS connection -- client side
403 * Returns: true on success
406 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
410 tls = new_tls_connection(ctx, bsock->fd);
412 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
418 /* Initiate TLS Negotiation */
419 if (!tls_bsock_connect(bsock)) {
423 if (!tls_postconnect_verify_host(tls, bsock->host())) {
424 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"),
431 free_tls_connection(tls);
436 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
438 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
441 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
443 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
446 #endif /* HAVE_TLS */
449 * Wait for a specified time for data to appear on
450 * the BSOCK connection.
452 * Returns: 1 if data available
456 int bnet_wait_data(BSOCK * bsock, int sec)
462 FD_SET((unsigned)bsock->fd, &fdset);
466 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
467 case 0: /* timeout */
471 bsock->b_errno = errno;
472 if (errno == EINTR) {
475 return -1; /* error return */
484 * As above, but returns on interrupt
486 int bnet_wait_data_intr(BSOCK * bsock, int sec)
492 FD_SET((unsigned)bsock->fd, &fdset);
495 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
496 case 0: /* timeout */
500 bsock->b_errno = errno;
501 return -1; /* error return */
508 #ifndef NETDB_INTERNAL
509 #define NETDB_INTERNAL -1 /* See errno. */
511 #ifndef NETDB_SUCCESS
512 #define NETDB_SUCCESS 0 /* No problem. */
514 #ifndef HOST_NOT_FOUND
515 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
518 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
521 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
524 #define NO_DATA 4 /* Valid name, no data record of requested type. */
528 * Get human readable error for gethostbyname()
530 static const char *gethost_strerror()
539 msg = _("No problem.");
542 msg = _("Authoritative answer for host not found.");
545 msg = _("Non-authoritative for host not found, or ServerFail.");
548 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
551 msg = _("Valid name, no data record of resquested type.");
554 msg = _("Unknown error.");
562 static IPADDR *add_any(int family)
564 IPADDR *addr = New(IPADDR(family));
565 addr->set_type(IPADDR::R_MULTIPLE);
566 addr->set_addr_any();
570 static const char *resolv_host(int family, const char *host, dlist * addr_list)
575 P(ip_mutex); /* gethostbyname() is not thread safe */
576 #ifdef HAVE_GETHOSTBYNAME2
577 if ((hp = gethostbyname2(host, family)) == NULL) {
579 if ((hp = gethostbyname(host)) == NULL) {
581 /* may be the strerror give not the right result -:( */
582 errmsg = gethost_strerror();
587 for (p = hp->h_addr_list; *p != 0; p++) {
588 IPADDR *addr = New(IPADDR(hp->h_addrtype));
589 addr->set_type(IPADDR::R_MULTIPLE);
590 if (addr->get_family() == AF_INET) {
591 addr->set_addr4((struct in_addr*)*p);
595 addr->set_addr6((struct in6_addr*)*p);
598 addr_list->append(addr);
606 * i host = 0 mean INADDR_ANY only ipv4
608 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
610 struct in_addr inaddr;
614 struct in6_addr inaddr6;
617 dlist *addr_list = New(dlist(addr, &addr->link));
618 if (!host || host[0] == '\0') {
620 addr_list->append(add_any(family));
622 addr_list->append(add_any(AF_INET));
624 addr_list->append(add_any(AF_INET6));
627 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
628 addr = New(IPADDR(AF_INET));
629 addr->set_type(IPADDR::R_MULTIPLE);
630 addr->set_addr4(&inaddr);
631 addr_list->append(addr);
634 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
635 addr = New(IPADDR(AF_INET6));
636 addr->set_type(IPADDR::R_MULTIPLE);
637 addr->set_addr6(&inaddr6);
638 addr_list->append(addr);
643 errmsg = resolv_host(family, host, addr_list);
646 free_addresses(addr_list);
650 errmsg = resolv_host(AF_INET, host, addr_list);
653 errmsg = resolv_host(AF_INET6, host, addr_list);
658 free_addresses(addr_list);
667 * Open a TCP connection to the UPS network server
669 * Returns BSOCK * pointer on success
672 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
673 int port, int *fatal)
678 bool connected = false;
684 * Fill in the structure serv_addr with the address of
685 * the server that we want to connect with.
687 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
688 /* Note errstr is not malloc'ed */
689 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
691 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
697 foreach_dlist(ipaddr, addr_list) {
698 ipaddr->set_port_net(htons(port));
699 char allbuf[256 * 10];
701 Dmsg2(100, "Current %sAll %s\n",
702 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
703 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
704 /* Open a TCP socket */
705 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
709 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
710 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
714 * Keep socket from timing out from inactivity
716 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
718 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
721 /* connect to server */
722 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
733 free_addresses(addr_list);
738 * Keep socket from timing out from inactivity
739 * Do this a second time out of paranoia
741 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
743 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
746 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
747 free_addresses(addr_list);
752 * Try to connect to host for max_retry_time at retry_time intervals.
754 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
755 const char *name, char *host, char *service, int port,
762 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
763 i -= retry_interval) {
765 if (fatal || (jcr && job_canceled(jcr))) {
768 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
769 name, host, port, be.strerror());
771 i = 60 * 5; /* complain again in 5 minutes */
773 Qmsg4(jcr, M_WARNING, 0, _(
774 "Could not connect to %s on %s:%d. ERR=%s\n"
775 "Retrying ...\n"), name, host, port, be.strerror());
777 bmicrosleep(retry_interval, 0);
778 max_retry_time -= retry_interval;
779 if (max_retry_time <= 0) {
780 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
781 name, host, port, be.strerror());
790 * Return the string for the error that occurred
791 * on the socket. Only the first error is retained.
793 const char *bnet_strerror(BSOCK * bsock)
796 if (bsock->errmsg == NULL) {
797 bsock->errmsg = get_pool_memory(PM_MESSAGE);
799 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
800 return bsock->errmsg;
804 * Format and send a message
805 * Returns: false on error
808 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
813 if (bs->errors || bs->terminated) {
816 /* This probably won't work, but we vsnprintf, then if we
817 * get a negative length or a length greater than our buffer
818 * (depending on which library is used), the printf was truncated, so
819 * get a bigger buffer and try again.
822 maxlen = sizeof_pool_memory(bs->msg) - 1;
823 va_start(arg_ptr, fmt);
824 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
826 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
829 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
832 // return bnet_send(bs);
835 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
836 #if !defined(HAVE_WIN32)
837 if (bs->peer_addr.sin_family == 0) {
838 socklen_t salen = sizeof(bs->peer_addr);
839 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
840 if (rval < 0) return rval;
842 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
851 * Set the network buffer size, suggested size is in size.
852 * Actual size obtained is returned in bs->msglen
854 * Returns: 0 on failure
857 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
859 uint32_t dbuf_size, start_size;
860 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
863 opt = IPTOS_THROUGHPUT;
864 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
870 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
872 start_size = dbuf_size;
873 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
874 Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
877 if (rw & BNET_SETBUF_READ) {
878 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
879 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
881 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
882 dbuf_size -= TAPE_BSIZE;
884 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
885 if (dbuf_size != start_size) {
886 Qmsg1(bs->jcr(), M_WARNING, 0,
887 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
889 if (dbuf_size % TAPE_BSIZE != 0) {
890 Qmsg1(bs->jcr(), M_ABORT, 0,
891 _("Network buffer size %d not multiple of tape block size.\n"),
898 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
900 start_size = dbuf_size;
901 if (rw & BNET_SETBUF_WRITE) {
902 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
903 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
905 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
906 dbuf_size -= TAPE_BSIZE;
908 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
909 if (dbuf_size != start_size) {
910 Qmsg1(bs->jcr(), M_WARNING, 0,
911 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
913 if (dbuf_size % TAPE_BSIZE != 0) {
914 Qmsg1(bs->jcr(), M_ABORT, 0,
915 _("Network buffer size %d not multiple of tape block size.\n"),
920 bs->msglen = dbuf_size;
925 * Set socket non-blocking
926 * Returns previous socket flag
928 int bnet_set_nonblocking (BSOCK *bsock) {
932 /* Get current flags */
933 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
935 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
938 /* Set O_NONBLOCK flag */
939 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
941 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
950 flags = bsock->blocking;
951 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
959 * Set socket blocking
960 * Returns previous socket flags
962 int bnet_set_blocking (BSOCK *bsock)
966 /* Get current flags */
967 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
969 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
972 /* Set O_NONBLOCK flag */
973 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
975 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
984 flags = bsock->blocking;
985 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
993 * Restores socket flags
995 void bnet_restore_blocking (BSOCK *bsock, int flags)
998 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1000 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1003 bsock->blocking = (flags & O_NONBLOCK);
1005 u_long ioctlArg = flags;
1007 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1008 bsock->blocking = 1;
1014 * Send a network "signal" to the other end
1015 * This consists of sending a negative packet length
1017 * Returns: false on failure
1020 bool bnet_sig(BSOCK * bs, int signal)
1022 return bs->signal(signal);
1026 * Convert a network "signal" code into
1027 * human readable ASCII.
1029 const char *bnet_sig_to_ascii(BSOCK * bs)
1031 static char buf[30];
1032 switch (bs->msglen) {
1034 return "BNET_EOD"; /* end of data stream */
1036 return "BNET_EOD_POLL";
1038 return "BNET_STATUS";
1039 case BNET_TERMINATE:
1040 return "BNET_TERMINATE"; /* terminate connection */
1043 case BNET_HEARTBEAT:
1044 return "BNET_HEARTBEAT";
1045 case BNET_HB_RESPONSE:
1046 return "BNET_HB_RESPONSE";
1048 return "BNET_PROMPT";
1050 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1056 /* Initialize internal socket structure.
1057 * This probably should be done in net_open
1059 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1060 struct sockaddr *client_addr)
1062 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1063 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1064 memset(bsock, 0, sizeof(BSOCK));
1068 bsock->blocking = 1;
1069 bsock->msg = get_pool_memory(PM_MESSAGE);
1070 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1071 bsock->set_who(bstrdup(who));
1072 bsock->set_host(bstrdup(host));
1073 bsock->set_port(port);
1074 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1075 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1077 * ****FIXME**** reduce this to a few hours once
1078 * heartbeats are implemented
1080 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1081 bsock->set_jcr(jcr);
1085 BSOCK *dup_bsock(BSOCK * osock)
1087 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1088 memcpy(bsock, osock, sizeof(BSOCK));
1089 bsock->msg = get_pool_memory(PM_MESSAGE);
1090 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1092 bsock->set_who(bstrdup(osock->who()));
1094 if (osock->host()) {
1095 bsock->set_host(bstrdup(osock->host()));
1097 bsock->duped = true;
1101 /* Close the network connection */
1102 void bnet_close(BSOCK * bsock)
1104 bsock->close(); /* this calls destroy */
1107 void term_bsock(BSOCK * bsock)