2 * Network Utility Routines
6 * Adapted and enhanced for Bacula, originally written
7 * for inclusion in the Apcupsd package
12 Copyright (C) 2000-2004 Kern Sibbald and John Walker
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2.1 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
36 extern time_t watchdog_time;
39 #define INADDR_NONE -1
42 #ifndef ENODATA /* not defined on BSD systems */
47 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
48 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
49 #define socketClose(fd) closesocket(fd)
51 #define socketRead(fd, buf, len) read(fd, buf, len)
52 #define socketWrite(fd, buf, len) write(fd, buf, len)
53 #define socketClose(fd) close(fd)
57 #ifdef HAVE_OLD_SOCKOPT
58 int inet_aton(const char *cp, struct in_addr *inp)
60 struct in_addr inaddr;
62 if((inaddr.s_addr = inet_addr(cp)) != INADDR_NONE) {
63 inp->s_addr = inaddr.s_addr;
71 * Read a nbytes from the network.
72 * It is possible that the total bytes require in several
76 static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
84 nread = socketRead(bsock->fd, ptr, nleft);
85 if (bsock->timed_out || bsock->terminated) {
88 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
90 return nread; /* error, or EOF */
95 return nbytes - nleft; /* return >= 0 */
99 * Write nbytes to the network.
100 * It may require several writes.
103 static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
105 int32_t nleft, nwritten;
108 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
109 if (nwritten != nbytes) {
111 bsock->b_errno = errno;
112 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
114 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
115 errno = bsock->b_errno;
124 nwritten = socketWrite(bsock->fd, ptr, nleft);
125 if (bsock->timed_out || bsock->terminated) {
128 } while (nwritten == -1 && errno == EINTR);
130 * If connection is non-blocking, we will get EAGAIN, so
131 * use select() to keep from consuming all the CPU
134 if (nwritten == -1 && errno == EAGAIN) {
139 FD_SET((unsigned)bsock->fd, &fdset);
142 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
146 return nwritten; /* error */
151 return nbytes - nleft;
155 * Receive a message from the other end. Each message consists of
156 * two packets. The first is a header that contains the size
157 * of the data that follows in the second packet.
158 * Returns number of bytes read (may return zero)
159 * Returns -1 on signal (BNET_SIGNAL)
160 * Returns -2 on hard end of file (BNET_HARDEOF)
161 * Returns -3 on error (BNET_ERROR)
163 * Unfortunately, it is a bit complicated because we have these
166 * 2. Signal including end of data stream
167 * 3. Hard end of file
169 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
171 int32_t bnet_recv(BSOCK * bsock)
176 ASSERT(bsock != NULL);
179 if (bsock->errors || bsock->terminated) {
183 bsock->read_seqno++; /* bump sequence number */
184 bsock->timer_start = watchdog_time; /* set start wait time */
185 bsock->timed_out = 0;
186 /* get data size -- in int32_t */
187 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
188 bsock->timer_start = 0; /* clear timer */
189 /* probably pipe broken because client died */
191 bsock->b_errno = ENODATA;
193 bsock->b_errno = errno;
196 return BNET_HARDEOF; /* assume hard EOF received */
198 bsock->timer_start = 0; /* clear timer */
199 if (nbytes != sizeof(int32_t)) {
201 bsock->b_errno = EIO;
202 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
203 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
207 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
209 if (pktsiz == 0) { /* No data transferred */
210 bsock->timer_start = 0; /* clear timer */
213 return 0; /* zero bytes read */
216 /* If signal or packet size too big */
217 if (pktsiz < 0 || pktsiz > 1000000) {
218 if (pktsiz > 0) { /* if packet too big */
219 Qmsg3(bsock->jcr, M_FATAL, 0,
220 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
221 bsock->who, bsock->host, bsock->port);
222 pktsiz = BNET_TERMINATE; /* hang up */
224 if (pktsiz == BNET_TERMINATE) {
225 bsock->terminated = 1;
227 bsock->timer_start = 0; /* clear timer */
228 bsock->b_errno = ENODATA;
229 bsock->msglen = pktsiz; /* signal code */
230 return BNET_SIGNAL; /* signal */
233 /* Make sure the buffer is big enough + one byte for EOS */
234 if (pktsiz >= (int32_t) sizeof_pool_memory(bsock->msg)) {
235 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
238 bsock->timer_start = watchdog_time; /* set start wait time */
239 bsock->timed_out = 0;
240 /* now read the actual data */
241 if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
242 bsock->timer_start = 0; /* clear timer */
244 bsock->b_errno = ENODATA;
246 bsock->b_errno = errno;
249 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
250 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
253 bsock->timer_start = 0; /* clear timer */
255 bsock->msglen = nbytes;
256 if (nbytes != pktsiz) {
257 bsock->b_errno = EIO;
259 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
260 pktsiz, nbytes, bsock->who, bsock->host, bsock->port);
263 /* always add a zero by to properly terminate any
264 * string that was send to us. Note, we ensured above that the
265 * buffer is at least one byte longer than the message length.
267 bsock->msg[nbytes] = 0; /* terminate in case it is a string */
268 sm_check(__FILE__, __LINE__, false);
269 return nbytes; /* return actual length of message */
274 * Return 1 if there are errors on this bsock or it is closed,
275 * i.e. stop communicating on this line.
277 bool is_bnet_stop(BSOCK * bsock)
279 return bsock->errors || bsock->terminated;
283 * Return number of errors on socket
285 int is_bnet_error(BSOCK * bsock)
287 return bsock->errors;
291 * Call here after error during closing to suppress error
292 * messages which are due to the other end shutting down too.
294 void bnet_suppress_error_messages(BSOCK * bsock, bool flag)
296 bsock->suppress_error_msgs = flag;
301 * Transmit spooled data now to a BSOCK
303 int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size),
308 ssize_t last = 0, size = 0;
311 rewind(bsock->spool_fd);
312 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) ==
314 size += sizeof(int32_t);
315 bsock->msglen = ntohl(pktsiz);
316 if (bsock->msglen > 0) {
317 if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) {
318 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
320 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
321 if (nbytes != (size_t) bsock->msglen) {
323 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
324 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
326 update_attr_spool_size(tsize - last);
330 if ((++count & 0x3F) == 0) {
331 update_attr_spool_size(size - last);
337 update_attr_spool_size(tsize - last);
338 if (ferror(bsock->spool_fd)) {
340 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"),
349 * Send a message over the network. The send consists of
350 * two network packets. The first is sends a 32 bit integer containing
351 * the length of the data packet which follows.
353 * Returns: false on failure
356 bool bnet_send(BSOCK * bsock)
361 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
364 pktsiz = htonl((int32_t) bsock->msglen);
365 /* send int32_t containing size of data packet */
366 bsock->timer_start = watchdog_time; /* start timer */
367 bsock->timed_out = 0;
368 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
369 bsock->timer_start = 0; /* clear timer */
370 if (rc != sizeof(int32_t)) {
371 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
372 bsock->terminated = 1;
373 return false; /* ignore any errors */
377 bsock->b_errno = EIO;
379 bsock->b_errno = errno;
382 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
383 Qmsg4(bsock->jcr, M_ERROR, 0,
384 _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
385 bsock->host, bsock->port, bnet_strerror(bsock));
388 Qmsg5(bsock->jcr, M_ERROR, 0,
389 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who,
390 bsock->host, bsock->port, bsock->msglen, rc);
395 bsock->out_msg_no++; /* increment message number */
396 if (bsock->msglen <= 0) { /* length only? */
397 return true; /* yes, no data */
400 /* send data packet */
401 bsock->timer_start = watchdog_time; /* start timer */
402 bsock->timed_out = 0;
403 rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
404 bsock->timer_start = 0; /* clear timer */
405 if (rc != bsock->msglen) {
408 bsock->b_errno = EIO;
410 bsock->b_errno = errno;
413 if (!bsock->suppress_error_msgs) {
414 Qmsg4(bsock->jcr, M_ERROR, 0,
415 _("Write error sending to %s:%s:%d: ERR=%s\n"), bsock->who,
416 bsock->host, bsock->port, bnet_strerror(bsock));
419 Qmsg5(bsock->jcr, M_ERROR, 0,
420 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
421 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
429 * Establish an SSL connection -- server side
430 * Codes that ssl_need and ssl_has can take
431 * BNET_SSL_NONE I cannot do ssl
432 * BNET_SSL_OK I can do ssl, but it is not required on my end
433 * BNET_SSL_REQUIRED ssl is required on my end
435 int bnet_ssl_server(BSOCK * bsock, char *password, int ssl_need, int ssl_has)
437 /* Check to see if what we need (ssl_need) corresponds to what he has (ssl_has) */
438 /* The other side expects a response from us */
443 * Establish an SSL connection -- client side
445 int bnet_ssl_client(BSOCK * bsock, char *password, int ssl_need)
447 /* We are the client so we must wait for the server to notify us */
453 * Wait for a specified time for data to appear on
454 * the BSOCK connection.
456 * Returns: 1 if data available
460 int bnet_wait_data(BSOCK * bsock, int sec)
466 FD_SET((unsigned)bsock->fd, &fdset);
470 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
471 case 0: /* timeout */
475 bsock->b_errno = errno;
476 if (errno == EINTR || errno == EAGAIN) {
479 return -1; /* error return */
488 * As above, but returns on interrupt
490 int bnet_wait_data_intr(BSOCK * bsock, int sec)
496 FD_SET((unsigned)bsock->fd, &fdset);
500 switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
501 case 0: /* timeout */
505 bsock->b_errno = errno;
506 return -1; /* error return */
514 #ifndef NETDB_INTERNAL
515 #define NETDB_INTERNAL -1 /* See errno. */
517 #ifndef NETDB_SUCCESS
518 #define NETDB_SUCCESS 0 /* No problem. */
520 #ifndef HOST_NOT_FOUND
521 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
524 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
527 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
530 #define NO_DATA 4 /* Valid name, no data record of requested type. */
534 * Get human readable error for gethostbyname()
536 static const char *gethost_strerror()
541 msg = strerror(errno);
547 msg = "Authoritative answer for host not found.";
550 msg = "Non-authoritative for host not found, or ServerFail.";
553 msg = "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
556 msg = "Valid name, no data record of resquested type.";
559 msg = "Unknown error.";
565 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
568 static IPADDR *add_any(int family)
570 IPADDR *addr = New(IPADDR(family));
571 addr->set_type(IPADDR::R_MULTIPLE);
572 addr->set_addr_any();
576 static const char *resolv_host(int family, const char *host, dlist * addr_list)
582 #ifdef HAVE_GETHOSTBYNAME2
583 if ((hp = gethostbyname2(host, family)) == NULL) {
585 if ((hp = gethostbyname(host)) == NULL) {
587 /* may be the strerror give not the right result -:( */
588 errmsg = gethost_strerror();
593 for (p = hp->h_addr_list; *p != 0; p++) {
594 IPADDR *addr = New(IPADDR(hp->h_addrtype));
595 addr->set_type(IPADDR::R_MULTIPLE);
596 if (addr->get_family() == AF_INET) {
597 addr->set_addr4((struct in_addr*)*p);
601 addr->set_addr6((struct in6_addr*)*p);
604 addr_list->append(addr);
612 * i host = 0 mean INADDR_ANY only ipv4
614 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
616 struct in_addr inaddr;
620 struct in6_addr inaddr6;
623 dlist *addr_list = New(dlist(addr, &addr->link));
624 if (!host || host[0] == '\0') {
626 addr_list->append(add_any(family));
628 addr_list->append(add_any(AF_INET));
630 addr_list->append(add_any(AF_INET6));
633 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
634 addr = New(IPADDR(AF_INET));
635 addr->set_type(IPADDR::R_MULTIPLE);
636 addr->set_addr4(&inaddr);
637 addr_list->append(addr);
640 if (inet_pton(AF_INET6, host, &inaddr6) > 1) {
641 addr = New(IPADDR(AF_INET6));
642 addr->set_type(IPADDR::R_MULTIPLE);
643 addr->set_addr6(&inaddr6);
644 addr_list->append(addr);
649 errmsg = resolv_host(family, host, addr_list);
652 free_addresses(addr_list);
656 errmsg = resolv_host(AF_INET, host, addr_list);
659 errmsg = resolv_host(AF_INET6, host, addr_list);
664 free_addresses(addr_list);
673 * Open a TCP connection to the UPS network server
675 * Returns BSOCK * pointer on success
678 static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service,
679 int port, int *fatal)
684 bool connected = false;
690 * Fill in the structure serv_addr with the address of
691 * the server that we want to connect with.
693 if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) {
694 /* Note errstr is not malloc'ed */
695 Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
697 Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n",
703 foreach_dlist(ipaddr, addr_list) {
704 ipaddr->set_port_net(htons(port));
705 char allbuf[256 * 10];
707 Dmsg2(100, "Current %sAll %s\n",
708 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
709 build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
710 /* Open a TCP socket */
711 if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) {
715 Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n",
716 ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror());
720 * Keep socket from timing out from inactivity
722 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
724 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
727 /* connect to server */
728 if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) {
739 free_addresses(addr_list);
744 * Keep socket from timing out from inactivity
745 * Do this a second time out of paranoia
747 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
749 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
752 BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
753 free_addresses(addr_list);
758 * Try to connect to host for max_retry_time at retry_time intervals.
760 BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time,
761 const char *name, char *host, char *service, int port,
768 for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL;
769 i -= retry_interval) {
771 if (fatal || (jcr && job_canceled(jcr))) {
774 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
775 name, host, port, be.strerror());
777 i = 60 * 5; /* complain again in 5 minutes */
779 Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n"
780 "Retrying ...\n", name, host, port, be.strerror());
782 bmicrosleep(retry_interval, 0);
783 max_retry_time -= retry_interval;
784 if (max_retry_time <= 0) {
785 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
786 name, host, port, be.strerror());
795 * Return the string for the error that occurred
796 * on the socket. Only the first error is retained.
798 const char *bnet_strerror(BSOCK * bsock)
801 if (bsock->errmsg == NULL) {
802 bsock->errmsg = get_pool_memory(PM_MESSAGE);
804 pm_strcpy(bsock->errmsg, be.strerror(bsock->b_errno));
805 return bsock->errmsg;
809 * Format and send a message
810 * Returns: false on error
813 bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
818 if (bs->errors || bs->terminated) {
821 /* This probably won't work, but we vsnprintf, then if we
822 * get a negative length or a length greater than our buffer
823 * (depending on which library is used), the printf was truncated, so
824 * get a bigger buffer and try again.
827 maxlen = sizeof_pool_memory(bs->msg) - 1;
828 va_start(arg_ptr, fmt);
829 bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
831 if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) {
834 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
836 return bnet_send(bs);
840 * Set the network buffer size, suggested size is in size.
841 * Actual size obtained is returned in bs->msglen
843 * Returns: 0 on failure
846 bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
848 uint32_t dbuf_size, start_size;
849 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
852 opt = IPTOS_THROUGHPUT;
853 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t) & opt, sizeof(opt));
859 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
861 start_size = dbuf_size;
862 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size + 100)) == NULL) {
863 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
866 if (rw & BNET_SETBUF_READ) {
867 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
868 SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
870 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
871 dbuf_size -= TAPE_BSIZE;
873 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
874 if (dbuf_size != start_size) {
875 Qmsg1(bs->jcr, M_WARNING, 0,
876 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
878 if (dbuf_size % TAPE_BSIZE != 0) {
879 Qmsg1(bs->jcr, M_ABORT, 0,
880 _("Network buffer size %d not multiple of tape block size.\n"),
887 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
889 start_size = dbuf_size;
890 if (rw & BNET_SETBUF_WRITE) {
891 while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET,
892 SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) {
894 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
895 dbuf_size -= TAPE_BSIZE;
897 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
898 if (dbuf_size != start_size) {
899 Qmsg1(bs->jcr, M_WARNING, 0,
900 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
902 if (dbuf_size % TAPE_BSIZE != 0) {
903 Qmsg1(bs->jcr, M_ABORT, 0,
904 _("Network buffer size %d not multiple of tape block size.\n"),
909 bs->msglen = dbuf_size;
914 * Send a network "signal" to the other end
915 * This consists of sending a negative packet length
917 * Returns: false on failure
920 bool bnet_sig(BSOCK * bs, int sig)
923 return bnet_send(bs);
927 * Convert a network "signal" code into
928 * human readable ASCII.
930 const char *bnet_sig_to_ascii(BSOCK * bs)
933 switch (bs->msglen) {
935 return "BNET_EOD"; /* end of data stream */
937 return "BNET_EOD_POLL";
939 return "BNET_STATUS";
941 return "BNET_TERMINATE"; /* terminate connection */
945 return "BNET_HEARTBEAT";
946 case BNET_HB_RESPONSE:
947 return "BNET_HB_RESPONSE";
949 return "BNET_PROMPT";
951 sprintf(buf, "Unknown sig %d", bs->msglen);
957 /* Initialize internal socket structure.
958 * This probably should be done in net_open
960 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
961 struct sockaddr *client_addr)
963 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
964 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
965 memset(bsock, 0, sizeof(BSOCK));
968 bsock->msg = get_pool_memory(PM_MESSAGE);
969 bsock->errmsg = get_pool_memory(PM_MESSAGE);
970 bsock->who = bstrdup(who);
971 bsock->host = bstrdup(host);
973 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
975 * ****FIXME**** reduce this to a few hours once
976 * heartbeats are implemented
978 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
983 BSOCK *dup_bsock(BSOCK * osock)
985 BSOCK *bsock = (BSOCK *) malloc(sizeof(BSOCK));
986 memcpy(bsock, osock, sizeof(BSOCK));
987 bsock->msg = get_pool_memory(PM_MESSAGE);
988 bsock->errmsg = get_pool_memory(PM_MESSAGE);
990 bsock->who = bstrdup(osock->who);
993 bsock->host = bstrdup(osock->host);
999 /* Close the network connection */
1000 void bnet_close(BSOCK * bsock)
1004 for (; bsock != NULL; bsock = next) {
1006 if (!bsock->duped) {
1007 if (bsock->timed_out) {
1008 shutdown(bsock->fd, 2); /* discard any pending I/O */
1010 socketClose(bsock->fd); /* normal close */
1017 void term_bsock(BSOCK * bsock)
1020 free_pool_memory(bsock->msg);
1023 ASSERT(1 == 0); /* double close */
1025 if (bsock->errmsg) {
1026 free_pool_memory(bsock->errmsg);
1027 bsock->errmsg = NULL;