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
51 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
52 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
53 #define socketClose(fd) closesocket(fd)
55 #define socketRead(fd, buf, len) read(fd, buf, len)
56 #define socketWrite(fd, buf, len) write(fd, buf, len)
57 #define socketClose(fd) close(fd)
60 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
63 * Read a nbytes from the network.
64 * It is possible that the total bytes require in several
68 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
75 return (tls_bsock_readn(bsock, ptr, nbytes));
82 nread = socketRead(bsock->fd, ptr, nleft);
83 if (bsock->timed_out || bsock->terminated) {
90 if (errno == EAGAIN) {
91 bmicrosleep(0, 200000); /* try again in 200ms */
96 return nread; /* error, or EOF */
101 return nbytes - nleft; /* return >= 0 */
105 * Write nbytes to the network.
106 * It may require several writes.
109 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
111 int32_t nleft, nwritten;
114 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
115 if (nwritten != nbytes) {
117 bsock->b_errno = errno;
118 Qmsg1(bsock->jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
120 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
121 errno = bsock->b_errno;
130 return (tls_bsock_writen(bsock, ptr, nbytes));
132 #endif /* HAVE_TLS */
138 nwritten = socketWrite(bsock->fd, ptr, nleft);
139 if (bsock->timed_out || bsock->terminated) {
142 } while (nwritten == -1 && errno == EINTR);
144 * If connection is non-blocking, we will get EAGAIN, so
145 * use select() to keep from consuming all the CPU
148 if (nwritten == -1 && errno == EAGAIN) {
153 FD_SET((unsigned)bsock->fd, &fdset);
156 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
160 return nwritten; /* error */
165 return nbytes - nleft;
169 * Receive a message from the other end. Each message consists of
170 * two packets. The first is a header that contains the size
171 * of the data that follows in the second packet.
172 * Returns number of bytes read (may return zero)
173 * Returns -1 on signal (BNET_SIGNAL)
174 * Returns -2 on hard end of file (BNET_HARDEOF)
175 * Returns -3 on error (BNET_ERROR)
177 * Unfortunately, it is a bit complicated because we have these
180 * 2. Signal including end of data stream
181 * 3. Hard end of file
183 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
185 int32_t bnet_recv(BSOCK * bsock)
187 return bsock->recv();
192 * Return 1 if there are errors on this bsock or it is closed,
193 * i.e. stop communicating on this line.
195 bool is_bnet_stop(BSOCK * bsock)
197 return bsock->errors || bsock->terminated;
201 * Return number of errors on socket
203 int is_bnet_error(BSOCK * bsock)
205 errno = bsock->b_errno;
206 return bsock->errors;
210 * Call here after error during closing to suppress error
211 * messages which are due to the other end shutting down too.
213 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
215 bsock->suppress_error_msgs = flag;
220 * Transmit spooled data now to a BSOCK
222 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
227 ssize_t last = 0, size = 0;
230 rewind(bsock->spool_fd);
231 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
233 size += sizeof(int32_t);
234 bsock->msglen = ntohl(pktsiz);
235 if (bsock->msglen > 0) {
236 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
237 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
239 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
240 if (nbytes != (size_t) bsock->msglen) {
242 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
243 Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
245 update_attr_spool_size(tsize - last);
249 if ((++count & 0x3F) == 0) {
250 update_attr_spool_size(size - last);
256 update_attr_spool_size(tsize - last);
257 if (ferror(bsock->spool_fd)) {
259 Qmsg1(bsock->jcr(), M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
268 * Send a message over the network. The send consists of
269 * two network packets. The first is sends a 32 bit integer containing
270 * the length of the data packet which follows.
272 * Returns: false on failure
275 bool bnet_send(BSOCK *bsock)
277 return bsock->send();
281 bool bnet_send(BSOCK * bsock)
286 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
289 pktsiz = htonl((int32_t)bsock->msglen);
290 /* send int32_t containing size of data packet */
291 bsock->timer_start = watchdog_time; /* start timer */
292 bsock->timed_out = 0;
293 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
294 bsock->timer_start = 0; /* clear timer */
295 if (rc != sizeof(int32_t)) {
296 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
297 bsock->terminated = 1;
298 return false; /* ignore any errors */
302 bsock->b_errno = EIO;
304 bsock->b_errno = errno;
307 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
308 Qmsg4(bsock->jcr(), M_ERROR, 0,
309 _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who,
310 bsock->host(), bsock->port(), bnet_strerror(bsock));
313 Qmsg5(bsock->jcr(), M_ERROR, 0,
314 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
315 sizeof(int32_t), bsock->who(),
316 bsock->host(), bsock->port(), rc);
321 bsock->out_msg_no++; /* increment message number */
322 if (bsock->msglen <= 0) { /* length only? */
323 return true; /* yes, no data */
326 /* send data packet */
327 bsock->timer_start = watchdog_time; /* start timer */
328 bsock->timed_out = 0;
329 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
330 bsock->timer_start = 0; /* clear timer */
331 if (rc != bsock->msglen) {
334 bsock->b_errno = EIO;
336 bsock->b_errno = errno;
339 if (!bsock->suppress_error_msgs) {
340 Qmsg5(bsock->jcr(), M_ERROR, 0,
341 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
342 bsock->msglen, bsock->who(),
343 bsock->host(), bsock->port(), bnet_strerror(bsock));
346 Qmsg5(bsock->jcr(), M_ERROR, 0,
347 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
348 bsock->msglen, bsock->who(), bsock->host(),
358 * Establish a TLS connection -- server side
359 * Returns: true on success
363 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
367 tls = new_tls_connection(ctx, bsock->fd);
369 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
375 /* Initiate TLS Negotiation */
376 if (!tls_bsock_accept(bsock)) {
377 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
382 if (!tls_postconnect_verify_cn(tls, verify_list)) {
383 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
384 " Peer certificate did not match a required commonName\n"),
392 free_tls_connection(tls);
398 * Establish a TLS connection -- client side
399 * Returns: true on success
402 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
406 tls = new_tls_connection(ctx, bsock->fd);
408 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
414 /* Initiate TLS Negotiation */
415 if (!tls_bsock_connect(bsock)) {
419 /* If there's an Allowed CN verify list, use that to validate the remote
420 * certificate's CN. Otherwise, we use standard host/CN matching. */
422 if (!tls_postconnect_verify_cn(tls, verify_list)) {
423 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
424 " Peer certificate did not match a required commonName\n"),
429 if (!tls_postconnect_verify_host(tls, bsock->host())) {
430 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"),
439 free_tls_connection(tls);
444 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
446 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
449 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list, int verify_hostname)
451 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
454 #endif /* HAVE_TLS */
457 * Wait for a specified time for data to appear on
458 * the BSOCK connection.
460 * Returns: 1 if data available
464 int bnet_wait_data(BSOCK * bsock, int sec)
470 FD_SET((unsigned)bsock->fd, &fdset);
474 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
475 case 0: /* timeout */
479 bsock->b_errno = errno;
480 if (errno == EINTR) {
483 return -1; /* error return */
492 * As above, but returns on interrupt
494 int bnet_wait_data_intr(BSOCK * bsock, int sec)
500 FD_SET((unsigned)bsock->fd, &fdset);
503 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
504 case 0: /* timeout */
508 bsock->b_errno = errno;
509 return -1; /* error return */
516 #ifndef NETDB_INTERNAL
517 #define NETDB_INTERNAL -1 /* See errno. */
519 #ifndef NETDB_SUCCESS
520 #define NETDB_SUCCESS 0 /* No problem. */
522 #ifndef HOST_NOT_FOUND
523 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
526 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
529 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
532 #define NO_DATA 4 /* Valid name, no data record of requested type. */
536 * Get human readable error for gethostbyname()
538 static const char *gethost_strerror()
547 msg = _("No problem.");
550 msg = _("Authoritative answer for host not found.");
553 msg = _("Non-authoritative for host not found, or ServerFail.");
556 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
559 msg = _("Valid name, no data record of resquested type.");
562 msg = _("Unknown error.");
570 static IPADDR *add_any(int family)
572 IPADDR *addr = New(IPADDR(family));
573 addr->set_type(IPADDR::R_MULTIPLE);
574 addr->set_addr_any();
578 static const char *resolv_host(int family, const char *host, dlist * addr_list)
583 P(ip_mutex); /* gethostbyname() is not thread safe */
584 #ifdef HAVE_GETHOSTBYNAME2
585 if ((hp = gethostbyname2(host, family)) == NULL) {
587 if ((hp = gethostbyname(host)) == NULL) {
589 /* may be the strerror give not the right result -:( */
590 errmsg = gethost_strerror();
595 for (p = hp->h_addr_list; *p != 0; p++) {
596 IPADDR *addr = New(IPADDR(hp->h_addrtype));
597 addr->set_type(IPADDR::R_MULTIPLE);
598 if (addr->get_family() == AF_INET) {
599 addr->set_addr4((struct in_addr*)*p);
603 addr->set_addr6((struct in6_addr*)*p);
606 addr_list->append(addr);
614 * i host = 0 mean INADDR_ANY only ipv4
616 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
618 struct in_addr inaddr;
622 struct in6_addr inaddr6;
625 dlist *addr_list = New(dlist(addr, &addr->link));
626 if (!host || host[0] == '\0') {
628 addr_list->append(add_any(family));
630 addr_list->append(add_any(AF_INET));
632 addr_list->append(add_any(AF_INET6));
635 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
636 addr = New(IPADDR(AF_INET));
637 addr->set_type(IPADDR::R_MULTIPLE);
638 addr->set_addr4(&inaddr);
639 addr_list->append(addr);
642 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
643 addr = New(IPADDR(AF_INET6));
644 addr->set_type(IPADDR::R_MULTIPLE);
645 addr->set_addr6(&inaddr6);
646 addr_list->append(addr);
651 errmsg = resolv_host(family, host, addr_list);
654 free_addresses(addr_list);
658 errmsg = resolv_host(AF_INET, host, addr_list);
661 errmsg = resolv_host(AF_INET6, host, addr_list);
666 free_addresses(addr_list);
675 * Open a TCP connection to the UPS network server
677 * Returns BSOCK * pointer on success
680 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
681 int port, int *fatal)
686 bool connected = false;
692 * Fill in the structure serv_addr with the address of
693 * the server that we want to connect with.
695 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
696 /* Note errstr is not malloc'ed */
697 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
699 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
705 foreach_dlist(ipaddr, addr_list) {
706 ipaddr->set_port_net(htons(port));
707 char allbuf[256 * 10];
709 Dmsg2(100, "Current %sAll %s\n",
710 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
711 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
712 /* Open a TCP socket */
713 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
717 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
718 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
722 * Keep socket from timing out from inactivity
724 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
726 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
729 /* connect to server */
730 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
741 free_addresses(addr_list);
746 * Keep socket from timing out from inactivity
747 * Do this a second time out of paranoia
749 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
751 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
754 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
755 free_addresses(addr_list);
760 * Try to connect to host for max_retry_time at retry_time intervals.
762 BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
763 const char *name, char *host, char *service, int port,
769 time_t begin_time = time(NULL);
772 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
773 i -= retry_interval) {
775 if (fatal || (jcr && job_canceled(jcr))) {
778 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
779 name, host, port, be.strerror());
781 i = 60 * 5; /* complain again in 5 minutes */
783 Qmsg4(jcr, M_WARNING, 0, _(
784 "Could not connect to %s on %s:%d. ERR=%s\n"
785 "Retrying ...\n"), name, host, port, be.strerror());
787 bmicrosleep(retry_interval, 0);
789 if (begin_time + max_retry_time <= now) {
790 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
791 name, host, port, be.strerror());
800 * Return the string for the error that occurred
801 * on the socket. Only the first error is retained.
803 const char *bnet_strerror(BSOCK * bsock)
806 if (bsock->errmsg == NULL) {
807 bsock->errmsg = get_pool_memory(PM_MESSAGE);
809 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
810 return bsock->errmsg;
814 * Format and send a message
815 * Returns: false on error
818 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
823 if (bs->errors || bs->terminated) {
826 /* This probably won't work, but we vsnprintf, then if we
827 * get a negative length or a length greater than our buffer
828 * (depending on which library is used), the printf was truncated, so
829 * get a bigger buffer and try again.
832 maxlen = sizeof_pool_memory(bs->msg) - 1;
833 va_start(arg_ptr, fmt);
834 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
836 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
839 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
842 // return bnet_send(bs);
845 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
846 #if !defined(HAVE_WIN32)
847 if (bs->peer_addr.sin_family == 0) {
848 socklen_t salen = sizeof(bs->peer_addr);
849 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
850 if (rval < 0) return rval;
852 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
861 * Set the network buffer size, suggested size is in size.
862 * Actual size obtained is returned in bs->msglen
864 * Returns: 0 on failure
867 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
869 uint32_t dbuf_size, start_size;
870 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
873 opt = IPTOS_THROUGHPUT;
874 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
880 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
882 start_size = dbuf_size;
883 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
884 Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
887 if (rw & BNET_SETBUF_READ) {
888 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
889 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
891 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
892 dbuf_size -= TAPE_BSIZE;
894 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
895 if (dbuf_size != start_size) {
896 Qmsg1(bs->jcr(), M_WARNING, 0,
897 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
899 if (dbuf_size % TAPE_BSIZE != 0) {
900 Qmsg1(bs->jcr(), M_ABORT, 0,
901 _("Network buffer size %d not multiple of tape block size.\n"),
908 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
910 start_size = dbuf_size;
911 if (rw & BNET_SETBUF_WRITE) {
912 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
913 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
915 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
916 dbuf_size -= TAPE_BSIZE;
918 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
919 if (dbuf_size != start_size) {
920 Qmsg1(bs->jcr(), M_WARNING, 0,
921 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
923 if (dbuf_size % TAPE_BSIZE != 0) {
924 Qmsg1(bs->jcr(), M_ABORT, 0,
925 _("Network buffer size %d not multiple of tape block size.\n"),
930 bs->msglen = dbuf_size;
935 * Set socket non-blocking
936 * Returns previous socket flag
938 int bnet_set_nonblocking (BSOCK *bsock) {
942 /* Get current flags */
943 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
945 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
948 /* Set O_NONBLOCK flag */
949 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
951 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
960 flags = bsock->blocking;
961 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
969 * Set socket blocking
970 * Returns previous socket flags
972 int bnet_set_blocking (BSOCK *bsock)
976 /* Get current flags */
977 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
979 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
982 /* Set O_NONBLOCK flag */
983 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
985 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
994 flags = bsock->blocking;
995 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1003 * Restores socket flags
1005 void bnet_restore_blocking (BSOCK *bsock, int flags)
1008 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1010 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1013 bsock->blocking = (flags & O_NONBLOCK);
1015 u_long ioctlArg = flags;
1017 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1018 bsock->blocking = 1;
1024 * Send a network "signal" to the other end
1025 * This consists of sending a negative packet length
1027 * Returns: false on failure
1030 bool bnet_sig(BSOCK * bs, int signal)
1032 return bs->signal(signal);
1036 * Convert a network "signal" code into
1037 * human readable ASCII.
1039 const char *bnet_sig_to_ascii(BSOCK * bs)
1041 static char buf[30];
1042 switch (bs->msglen) {
1044 return "BNET_EOD"; /* end of data stream */
1046 return "BNET_EOD_POLL";
1048 return "BNET_STATUS";
1049 case BNET_TERMINATE:
1050 return "BNET_TERMINATE"; /* terminate connection */
1053 case BNET_HEARTBEAT:
1054 return "BNET_HEARTBEAT";
1055 case BNET_HB_RESPONSE:
1056 return "BNET_HB_RESPONSE";
1058 return "BNET_PROMPT";
1060 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1066 /* Initialize internal socket structure.
1067 * This probably should be done in net_open
1069 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1070 struct sockaddr *client_addr)
1072 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1073 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1074 memset(bsock, 0, sizeof(BSOCK));
1078 bsock->blocking = 1;
1079 bsock->msg = get_pool_memory(PM_MESSAGE);
1080 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1081 bsock->set_who(bstrdup(who));
1082 bsock->set_host(bstrdup(host));
1083 bsock->set_port(port);
1084 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1085 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1087 * ****FIXME**** reduce this to a few hours once
1088 * heartbeats are implemented
1090 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1091 bsock->set_jcr(jcr);
1095 BSOCK *dup_bsock(BSOCK * osock)
1097 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1098 memcpy(bsock, osock, sizeof(BSOCK));
1099 bsock->msg = get_pool_memory(PM_MESSAGE);
1100 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1102 bsock->set_who(bstrdup(osock->who()));
1104 if (osock->host()) {
1105 bsock->set_host(bstrdup(osock->host()));
1107 bsock->duped = true;
1111 /* Close the network connection */
1112 void bnet_close(BSOCK * bsock)
1114 bsock->close(); /* this calls destroy */
1117 void term_bsock(BSOCK * bsock)