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, utime_t max_retry_time,
755 const char *name, char *host, char *service, int port,
761 time_t begin_time = time(NULL);
764 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
765 i -= retry_interval) {
767 if (fatal || (jcr && job_canceled(jcr))) {
770 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
771 name, host, port, be.strerror());
773 i = 60 * 5; /* complain again in 5 minutes */
775 Qmsg4(jcr, M_WARNING, 0, _(
776 "Could not connect to %s on %s:%d. ERR=%s\n"
777 "Retrying ...\n"), name, host, port, be.strerror());
779 bmicrosleep(retry_interval, 0);
781 if (begin_time + max_retry_time <= now) {
782 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
783 name, host, port, be.strerror());
792 * Return the string for the error that occurred
793 * on the socket. Only the first error is retained.
795 const char *bnet_strerror(BSOCK * bsock)
798 if (bsock->errmsg == NULL) {
799 bsock->errmsg = get_pool_memory(PM_MESSAGE);
801 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
802 return bsock->errmsg;
806 * Format and send a message
807 * Returns: false on error
810 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
815 if (bs->errors || bs->terminated) {
818 /* This probably won't work, but we vsnprintf, then if we
819 * get a negative length or a length greater than our buffer
820 * (depending on which library is used), the printf was truncated, so
821 * get a bigger buffer and try again.
824 maxlen = sizeof_pool_memory(bs->msg) - 1;
825 va_start(arg_ptr, fmt);
826 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
828 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
831 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
834 // return bnet_send(bs);
837 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
838 #if !defined(HAVE_WIN32)
839 if (bs->peer_addr.sin_family == 0) {
840 socklen_t salen = sizeof(bs->peer_addr);
841 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
842 if (rval < 0) return rval;
844 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
853 * Set the network buffer size, suggested size is in size.
854 * Actual size obtained is returned in bs->msglen
856 * Returns: 0 on failure
859 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
861 uint32_t dbuf_size, start_size;
862 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
865 opt = IPTOS_THROUGHPUT;
866 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
872 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
874 start_size = dbuf_size;
875 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
876 Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
879 if (rw & BNET_SETBUF_READ) {
880 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
881 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
883 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
884 dbuf_size -= TAPE_BSIZE;
886 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
887 if (dbuf_size != start_size) {
888 Qmsg1(bs->jcr(), M_WARNING, 0,
889 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
891 if (dbuf_size % TAPE_BSIZE != 0) {
892 Qmsg1(bs->jcr(), M_ABORT, 0,
893 _("Network buffer size %d not multiple of tape block size.\n"),
900 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
902 start_size = dbuf_size;
903 if (rw & BNET_SETBUF_WRITE) {
904 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
905 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
907 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
908 dbuf_size -= TAPE_BSIZE;
910 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
911 if (dbuf_size != start_size) {
912 Qmsg1(bs->jcr(), M_WARNING, 0,
913 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
915 if (dbuf_size % TAPE_BSIZE != 0) {
916 Qmsg1(bs->jcr(), M_ABORT, 0,
917 _("Network buffer size %d not multiple of tape block size.\n"),
922 bs->msglen = dbuf_size;
927 * Set socket non-blocking
928 * Returns previous socket flag
930 int bnet_set_nonblocking (BSOCK *bsock) {
934 /* Get current flags */
935 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
937 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
940 /* Set O_NONBLOCK flag */
941 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
943 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
952 flags = bsock->blocking;
953 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
961 * Set socket blocking
962 * Returns previous socket flags
964 int bnet_set_blocking (BSOCK *bsock)
968 /* Get current flags */
969 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
971 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
974 /* Set O_NONBLOCK flag */
975 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
977 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
986 flags = bsock->blocking;
987 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
995 * Restores socket flags
997 void bnet_restore_blocking (BSOCK *bsock, int flags)
1000 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1002 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1005 bsock->blocking = (flags & O_NONBLOCK);
1007 u_long ioctlArg = flags;
1009 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1010 bsock->blocking = 1;
1016 * Send a network "signal" to the other end
1017 * This consists of sending a negative packet length
1019 * Returns: false on failure
1022 bool bnet_sig(BSOCK * bs, int signal)
1024 return bs->signal(signal);
1028 * Convert a network "signal" code into
1029 * human readable ASCII.
1031 const char *bnet_sig_to_ascii(BSOCK * bs)
1033 static char buf[30];
1034 switch (bs->msglen) {
1036 return "BNET_EOD"; /* end of data stream */
1038 return "BNET_EOD_POLL";
1040 return "BNET_STATUS";
1041 case BNET_TERMINATE:
1042 return "BNET_TERMINATE"; /* terminate connection */
1045 case BNET_HEARTBEAT:
1046 return "BNET_HEARTBEAT";
1047 case BNET_HB_RESPONSE:
1048 return "BNET_HB_RESPONSE";
1050 return "BNET_PROMPT";
1052 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1058 /* Initialize internal socket structure.
1059 * This probably should be done in net_open
1061 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1062 struct sockaddr *client_addr)
1064 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1065 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1066 memset(bsock, 0, sizeof(BSOCK));
1070 bsock->blocking = 1;
1071 bsock->msg = get_pool_memory(PM_MESSAGE);
1072 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1073 bsock->set_who(bstrdup(who));
1074 bsock->set_host(bstrdup(host));
1075 bsock->set_port(port);
1076 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1077 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1079 * ****FIXME**** reduce this to a few hours once
1080 * heartbeats are implemented
1082 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1083 bsock->set_jcr(jcr);
1087 BSOCK *dup_bsock(BSOCK * osock)
1089 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1090 memcpy(bsock, osock, sizeof(BSOCK));
1091 bsock->msg = get_pool_memory(PM_MESSAGE);
1092 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1094 bsock->set_who(bstrdup(osock->who()));
1096 if (osock->host()) {
1097 bsock->set_host(bstrdup(osock->host()));
1099 bsock->duped = true;
1103 /* Close the network connection */
1104 void bnet_close(BSOCK * bsock)
1106 bsock->close(); /* this calls destroy */
1109 void term_bsock(BSOCK * bsock)