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, alist *verify_list)
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 there's an Allowed CN verify list, use that to validate the remote
424 * certificate's CN. Otherwise, we use standard host/CN matching. */
426 if (!tls_postconnect_verify_cn(tls, verify_list)) {
427 Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
428 " Peer certificate did not match a required commonName\n"),
433 if (!tls_postconnect_verify_host(tls, bsock->host())) {
434 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"),
443 free_tls_connection(tls);
448 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
450 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
453 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list, int verify_hostname)
455 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
458 #endif /* HAVE_TLS */
461 * Wait for a specified time for data to appear on
462 * the BSOCK connection.
464 * Returns: 1 if data available
468 int bnet_wait_data(BSOCK * bsock, int sec)
474 FD_SET((unsigned)bsock->fd, &fdset);
478 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
479 case 0: /* timeout */
483 bsock->b_errno = errno;
484 if (errno == EINTR) {
487 return -1; /* error return */
496 * As above, but returns on interrupt
498 int bnet_wait_data_intr(BSOCK * bsock, int sec)
504 FD_SET((unsigned)bsock->fd, &fdset);
507 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
508 case 0: /* timeout */
512 bsock->b_errno = errno;
513 return -1; /* error return */
520 #ifndef NETDB_INTERNAL
521 #define NETDB_INTERNAL -1 /* See errno. */
523 #ifndef NETDB_SUCCESS
524 #define NETDB_SUCCESS 0 /* No problem. */
526 #ifndef HOST_NOT_FOUND
527 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
530 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
533 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
536 #define NO_DATA 4 /* Valid name, no data record of requested type. */
540 * Get human readable error for gethostbyname()
542 static const char *gethost_strerror()
551 msg = _("No problem.");
554 msg = _("Authoritative answer for host not found.");
557 msg = _("Non-authoritative for host not found, or ServerFail.");
560 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
563 msg = _("Valid name, no data record of resquested type.");
566 msg = _("Unknown error.");
574 static IPADDR *add_any(int family)
576 IPADDR *addr = New(IPADDR(family));
577 addr->set_type(IPADDR::R_MULTIPLE);
578 addr->set_addr_any();
582 static const char *resolv_host(int family, const char *host, dlist * addr_list)
587 P(ip_mutex); /* gethostbyname() is not thread safe */
588 #ifdef HAVE_GETHOSTBYNAME2
589 if ((hp = gethostbyname2(host, family)) == NULL) {
591 if ((hp = gethostbyname(host)) == NULL) {
593 /* may be the strerror give not the right result -:( */
594 errmsg = gethost_strerror();
599 for (p = hp->h_addr_list; *p != 0; p++) {
600 IPADDR *addr = New(IPADDR(hp->h_addrtype));
601 addr->set_type(IPADDR::R_MULTIPLE);
602 if (addr->get_family() == AF_INET) {
603 addr->set_addr4((struct in_addr*)*p);
607 addr->set_addr6((struct in6_addr*)*p);
610 addr_list->append(addr);
618 * i host = 0 mean INADDR_ANY only ipv4
620 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
622 struct in_addr inaddr;
626 struct in6_addr inaddr6;
629 dlist *addr_list = New(dlist(addr, &addr->link));
630 if (!host || host[0] == '\0') {
632 addr_list->append(add_any(family));
634 addr_list->append(add_any(AF_INET));
636 addr_list->append(add_any(AF_INET6));
639 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
640 addr = New(IPADDR(AF_INET));
641 addr->set_type(IPADDR::R_MULTIPLE);
642 addr->set_addr4(&inaddr);
643 addr_list->append(addr);
646 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
647 addr = New(IPADDR(AF_INET6));
648 addr->set_type(IPADDR::R_MULTIPLE);
649 addr->set_addr6(&inaddr6);
650 addr_list->append(addr);
655 errmsg = resolv_host(family, host, addr_list);
658 free_addresses(addr_list);
662 errmsg = resolv_host(AF_INET, host, addr_list);
665 errmsg = resolv_host(AF_INET6, host, addr_list);
670 free_addresses(addr_list);
679 * Open a TCP connection to the UPS network server
681 * Returns BSOCK * pointer on success
684 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
685 int port, int *fatal)
690 bool connected = false;
696 * Fill in the structure serv_addr with the address of
697 * the server that we want to connect with.
699 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
700 /* Note errstr is not malloc'ed */
701 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() for host \"%s\" failed: ERR=%s\n"),
703 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
709 foreach_dlist(ipaddr, addr_list) {
710 ipaddr->set_port_net(htons(port));
711 char allbuf[256 * 10];
713 Dmsg2(100, "Current %sAll %s\n",
714 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
715 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
716 /* Open a TCP socket */
717 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
721 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
722 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
726 * Keep socket from timing out from inactivity
728 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
730 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
733 /* connect to server */
734 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
745 free_addresses(addr_list);
750 * Keep socket from timing out from inactivity
751 * Do this a second time out of paranoia
753 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
755 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
758 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
759 free_addresses(addr_list);
764 * Try to connect to host for max_retry_time at retry_time intervals.
766 BSOCK *bnet_connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
767 const char *name, char *host, char *service, int port,
773 time_t begin_time = time(NULL);
776 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
777 i -= retry_interval) {
779 if (fatal || (jcr && job_canceled(jcr))) {
782 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
783 name, host, port, be.strerror());
785 i = 60 * 5; /* complain again in 5 minutes */
787 Qmsg4(jcr, M_WARNING, 0, _(
788 "Could not connect to %s on %s:%d. ERR=%s\n"
789 "Retrying ...\n"), name, host, port, be.strerror());
791 bmicrosleep(retry_interval, 0);
793 if (begin_time + max_retry_time <= now) {
794 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
795 name, host, port, be.strerror());
804 * Return the string for the error that occurred
805 * on the socket. Only the first error is retained.
807 const char *bnet_strerror(BSOCK * bsock)
810 if (bsock->errmsg == NULL) {
811 bsock->errmsg = get_pool_memory(PM_MESSAGE);
813 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
814 return bsock->errmsg;
818 * Format and send a message
819 * Returns: false on error
822 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
827 if (bs->errors || bs->terminated) {
830 /* This probably won't work, but we vsnprintf, then if we
831 * get a negative length or a length greater than our buffer
832 * (depending on which library is used), the printf was truncated, so
833 * get a bigger buffer and try again.
836 maxlen = sizeof_pool_memory(bs->msg) - 1;
837 va_start(arg_ptr, fmt);
838 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
840 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
843 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
846 // return bnet_send(bs);
849 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
850 #if !defined(HAVE_WIN32)
851 if (bs->peer_addr.sin_family == 0) {
852 socklen_t salen = sizeof(bs->peer_addr);
853 int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
854 if (rval < 0) return rval;
856 if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
865 * Set the network buffer size, suggested size is in size.
866 * Actual size obtained is returned in bs->msglen
868 * Returns: 0 on failure
871 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
873 uint32_t dbuf_size, start_size;
874 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
877 opt = IPTOS_THROUGHPUT;
878 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
884 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
886 start_size = dbuf_size;
887 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
888 Qmsg0(bs->jcr(), M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
891 if (rw & BNET_SETBUF_READ) {
892 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
893 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
895 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
896 dbuf_size -= TAPE_BSIZE;
898 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
899 if (dbuf_size != start_size) {
900 Qmsg1(bs->jcr(), M_WARNING, 0,
901 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
903 if (dbuf_size % TAPE_BSIZE != 0) {
904 Qmsg1(bs->jcr(), M_ABORT, 0,
905 _("Network buffer size %d not multiple of tape block size.\n"),
912 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
914 start_size = dbuf_size;
915 if (rw & BNET_SETBUF_WRITE) {
916 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
917 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
919 Qmsg1(bs->jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
920 dbuf_size -= TAPE_BSIZE;
922 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
923 if (dbuf_size != start_size) {
924 Qmsg1(bs->jcr(), M_WARNING, 0,
925 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
927 if (dbuf_size % TAPE_BSIZE != 0) {
928 Qmsg1(bs->jcr(), M_ABORT, 0,
929 _("Network buffer size %d not multiple of tape block size.\n"),
934 bs->msglen = dbuf_size;
939 * Set socket non-blocking
940 * Returns previous socket flag
942 int bnet_set_nonblocking (BSOCK *bsock) {
946 /* Get current flags */
947 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
949 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
952 /* Set O_NONBLOCK flag */
953 if ((fcntl(bsock->fd, F_SETFL, oflags|O_NONBLOCK)) < 0) {
955 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
964 flags = bsock->blocking;
965 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
973 * Set socket blocking
974 * Returns previous socket flags
976 int bnet_set_blocking (BSOCK *bsock)
980 /* Get current flags */
981 if ((oflags = fcntl(bsock->fd, F_GETFL, 0)) < 0) {
983 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"), be.strerror());
986 /* Set O_NONBLOCK flag */
987 if ((fcntl(bsock->fd, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
989 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
998 flags = bsock->blocking;
999 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1000 bsock->blocking = 1;
1007 * Restores socket flags
1009 void bnet_restore_blocking (BSOCK *bsock, int flags)
1012 if ((fcntl(bsock->fd, F_SETFL, flags)) < 0) {
1014 Jmsg1(bsock->jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"), be.strerror());
1017 bsock->blocking = (flags & O_NONBLOCK);
1019 u_long ioctlArg = flags;
1021 ioctlsocket(bsock->fd, FIONBIO, &ioctlArg);
1022 bsock->blocking = 1;
1028 * Send a network "signal" to the other end
1029 * This consists of sending a negative packet length
1031 * Returns: false on failure
1034 bool bnet_sig(BSOCK * bs, int signal)
1036 return bs->signal(signal);
1040 * Convert a network "signal" code into
1041 * human readable ASCII.
1043 const char *bnet_sig_to_ascii(BSOCK * bs)
1045 static char buf[30];
1046 switch (bs->msglen) {
1048 return "BNET_EOD"; /* end of data stream */
1050 return "BNET_EOD_POLL";
1052 return "BNET_STATUS";
1053 case BNET_TERMINATE:
1054 return "BNET_TERMINATE"; /* terminate connection */
1057 case BNET_HEARTBEAT:
1058 return "BNET_HEARTBEAT";
1059 case BNET_HB_RESPONSE:
1060 return "BNET_HB_RESPONSE";
1062 return "BNET_PROMPT";
1064 sprintf(buf, _("Unknown sig %d"), (int)bs->msglen);
1070 /* Initialize internal socket structure.
1071 * This probably should be done in net_open
1073 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
1074 struct sockaddr *client_addr)
1076 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
1077 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1078 memset(bsock, 0, sizeof(BSOCK));
1082 bsock->blocking = 1;
1083 bsock->msg = get_pool_memory(PM_MESSAGE);
1084 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1085 bsock->set_who(bstrdup(who));
1086 bsock->set_host(bstrdup(host));
1087 bsock->set_port(port);
1088 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
1089 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
1091 * ****FIXME**** reduce this to a few hours once
1092 * heartbeats are implemented
1094 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
1095 bsock->set_jcr(jcr);
1099 BSOCK *dup_bsock(BSOCK * osock)
1101 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
1102 memcpy(bsock, osock, sizeof(BSOCK));
1103 bsock->msg = get_pool_memory(PM_MESSAGE);
1104 bsock->errmsg = get_pool_memory(PM_MESSAGE);
1106 bsock->set_who(bstrdup(osock->who()));
1108 if (osock->host()) {
1109 bsock->set_host(bstrdup(osock->host()));
1111 bsock->duped = true;
1115 /* Close the network connection */
1116 void bnet_close(BSOCK * bsock)
1118 bsock->close(); /* this calls destroy */
1121 void term_bsock(BSOCK * bsock)