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)
58 * Read a nbytes from the network.
59 * It is possible that the total bytes require in several
63 static int32_t read_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
71 nread = socketRead(bsock->fd, ptr, nleft);
72 if (bsock->timed_out || bsock->terminated) {
75 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
77 return nread; /* error, or EOF */
82 return nbytes - nleft; /* return >= 0 */
86 * Write nbytes to the network.
87 * It may require several writes.
90 static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
92 int32_t nleft, nwritten;
95 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
96 if (nwritten != nbytes) {
97 Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), strerror(errno));
98 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
107 nwritten = socketWrite(bsock->fd, ptr, nleft);
108 if (bsock->timed_out || bsock->terminated) {
111 } while (nwritten == -1 && errno == EINTR);
113 * If connection is non-blocking, we will get EAGAIN, so
114 * use select() to keep from consuming all the CPU
117 if (nwritten == -1 && errno == EAGAIN) {
122 FD_SET((unsigned)bsock->fd, &fdset);
125 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
129 return nwritten; /* error */
138 * Receive a message from the other end. Each message consists of
139 * two packets. The first is a header that contains the size
140 * of the data that follows in the second packet.
141 * Returns number of bytes read (may return zero)
142 * Returns -1 on signal (BNET_SIGNAL)
143 * Returns -2 on hard end of file (BNET_HARDEOF)
144 * Returns -3 on error (BNET_ERROR)
146 * Unfortunately, it is a bit complicated because we have these
149 * 2. Signal including end of data stream
150 * 3. Hard end of file
152 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
154 int32_t bnet_recv(BSOCK *bsock)
159 ASSERT(bsock != NULL);
160 mp_chr(bsock->msg)[0] = 0;
161 if (bsock->errors || bsock->terminated) {
165 bsock->read_seqno++; /* bump sequence number */
166 bsock->timer_start = watchdog_time; /* set start wait time */
167 bsock->timed_out = 0;
168 /* get data size -- in int32_t */
169 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
170 bsock->timer_start = 0; /* clear timer */
171 /* probably pipe broken because client died */
173 bsock->b_errno = ENODATA;
175 bsock->b_errno = errno;
178 return BNET_HARDEOF; /* assume hard EOF received */
180 bsock->timer_start = 0; /* clear timer */
181 if (nbytes != sizeof(int32_t)) {
183 bsock->b_errno = EIO;
184 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
185 sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port);
189 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
191 if (pktsiz == 0) { /* No data transferred */
192 bsock->timer_start = 0; /* clear timer */
195 return 0; /* zero bytes read */
198 /* If signal or packet size too big */
199 if (pktsiz < 0 || pktsiz > 1000000) {
200 if (pktsiz > 0) { /* if packet too big */
201 Qmsg3(bsock->jcr, M_FATAL, 0,
202 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
203 bsock->who, bsock->host, bsock->port);
204 pktsiz = BNET_TERMINATE; /* hang up */
206 if (pktsiz == BNET_TERMINATE) {
207 bsock->terminated = 1;
209 bsock->timer_start = 0; /* clear timer */
210 bsock->b_errno = ENODATA;
211 bsock->msglen = pktsiz; /* signal code */
212 return BNET_SIGNAL; /* signal */
215 /* Make sure the buffer is big enough + one byte for EOS */
216 if (pktsiz >= (int32_t)sizeof_pool_memory(bsock->msg)) {
217 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
220 bsock->timer_start = watchdog_time; /* set start wait time */
221 bsock->timed_out = 0;
222 /* now read the actual data */
223 if ((nbytes = read_nbytes(bsock, mp_chr(bsock->msg), pktsiz)) <= 0) {
224 bsock->timer_start = 0; /* clear timer */
226 bsock->b_errno = ENODATA;
228 bsock->b_errno = errno;
231 Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
232 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
235 bsock->timer_start = 0; /* clear timer */
237 bsock->msglen = nbytes;
238 if (nbytes != pktsiz) {
239 bsock->b_errno = EIO;
241 Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes,
242 bsock->who, bsock->host, bsock->port);
245 /* always add a zero by to properly terminate any
246 * string that was send to us. Note, we ensured above that the
247 * buffer is at least one byte longer than the message length.
249 mp_chr(bsock->msg)[nbytes] = 0; /* terminate in case it is a string */
250 sm_check(__FILE__, __LINE__, false);
251 return nbytes; /* return actual length of message */
256 * Return 1 if there are errors on this bsock or it is closed,
257 * i.e. stop communicating on this line.
259 bool is_bnet_stop(BSOCK *bsock)
261 return bsock->errors || bsock->terminated;
265 * Return number of errors on socket
267 int is_bnet_error(BSOCK *bsock)
269 return bsock->errors;
273 * Call here after error during closing to suppress error
274 * messages which are due to the other end shutting down too.
277 bnet_suppress_error_messages(BSOCK *bsock, bool flag)
279 bsock->suppress_error_msgs = flag;
284 * Transmit spooled data now to a BSOCK
286 int bnet_despool_to_bsock(BSOCK *bsock, void update_attr_spool_size(ssize_t size), ssize_t tsize)
290 ssize_t last = 0, size = 0;
293 rewind(bsock->spool_fd);
294 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) == sizeof(int32_t)) {
295 size += sizeof(int32_t);
296 bsock->msglen = ntohl(pktsiz);
297 if (bsock->msglen > 0) {
298 if (bsock->msglen > (int32_t)sizeof_pool_memory(bsock->msg)) {
299 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
301 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
302 if (nbytes != (size_t)bsock->msglen) {
303 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
304 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), strerror(errno));
305 update_attr_spool_size(tsize-last);
309 if ((++count & 0x3F) == 0) {
310 update_attr_spool_size(size-last);
316 update_attr_spool_size(tsize-last);
317 if (ferror(bsock->spool_fd)) {
318 Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), strerror(errno));
326 * Send a message over the network. The send consists of
327 * two network packets. The first is sends a 32 bit integer containing
328 * the length of the data packet which follows.
330 * Returns: 0 on failure
334 bnet_send(BSOCK *bsock)
339 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
342 pktsiz = htonl((int32_t)bsock->msglen);
343 /* send int32_t containing size of data packet */
344 bsock->timer_start = watchdog_time; /* start timer */
345 bsock->timed_out = 0;
346 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
347 bsock->timer_start = 0; /* clear timer */
348 if (rc != sizeof(int32_t)) {
349 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
350 bsock->terminated = 1;
351 return false; /* ignore any errors */
355 bsock->b_errno = EIO;
357 bsock->b_errno = errno;
360 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
361 Qmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
362 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
365 Qmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
366 bsock->who, bsock->host, bsock->port, bsock->msglen, rc);
371 bsock->out_msg_no++; /* increment message number */
372 if (bsock->msglen <= 0) { /* length only? */
373 return true; /* yes, no data */
376 /* send data packet */
377 bsock->timer_start = watchdog_time; /* start timer */
378 bsock->timed_out = 0;
379 rc = write_nbytes(bsock, mp_chr(bsock->msg), bsock->msglen);
380 bsock->timer_start = 0; /* clear timer */
381 if (rc != bsock->msglen) {
384 bsock->b_errno = EIO;
386 bsock->b_errno = errno;
389 if (!bsock->suppress_error_msgs) {
390 Qmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
391 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
394 Qmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
395 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
403 * Establish an SSL connection -- server side
404 * Codes that ssl_need and ssl_has can take
405 * BNET_SSL_NONE I cannot do ssl
406 * BNET_SSL_OK I can do ssl, but it is not required on my end
407 * BNET_SSL_REQUIRED ssl is required on my end
410 bnet_ssl_server(BSOCK *bsock, char *password, int ssl_need, int ssl_has)
412 /* Check to see if what we need (ssl_need) corresponds to what he has (ssl_has) */
413 /* The other side expects a response from us */
418 * Establish an SSL connection -- client side
420 int bnet_ssl_client(BSOCK *bsock, char *password, int ssl_need)
422 /* We are the client so we must wait for the server to notify us */
428 * Wait for a specified time for data to appear on
429 * the BSOCK connection.
431 * Returns: 1 if data available
436 bnet_wait_data(BSOCK *bsock, int sec)
442 FD_SET((unsigned)bsock->fd, &fdset);
446 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
447 case 0: /* timeout */
451 bsock->b_errno = errno;
452 if (errno == EINTR || errno == EAGAIN) {
455 return -1; /* error return */
464 * As above, but returns on interrupt
467 bnet_wait_data_intr(BSOCK *bsock, int sec)
473 FD_SET((unsigned)bsock->fd, &fdset);
477 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
478 case 0: /* timeout */
482 bsock->b_errno = errno;
483 return -1; /* error return */
491 #ifndef NETDB_INTERNAL
492 #define NETDB_INTERNAL -1 /* See errno. */
494 #ifndef NETDB_SUCCESS
495 #define NETDB_SUCCESS 0 /* No problem. */
497 #ifndef HOST_NOT_FOUND
498 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
501 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
504 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
507 #define NO_DATA 4 /* Valid name, no data record of requested type. */
511 * Get human readable error for gethostbyname()
513 static const char *gethost_strerror()
517 return strerror(errno);
519 return "No problem.";
521 return "Authoritative answer Host not found.";
523 return "Non-authoritative Host not found, or ServerFail.";
525 return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
527 return "Valid name, no data record of resquested type.";
529 return "Unknown error.";
534 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
537 * Convert a hostname or dotted IP address into
538 * a s_addr. We handle only IPv4.
540 static uint32_t *bget_host_ip(JCR *jcr, char *host)
542 struct in_addr inaddr;
543 uint32_t *addr_list; /* this really should be struct in_addr */
548 if ((inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
549 addr_list = (uint32_t *) malloc(sizeof(uint32_t) * 2);
550 addr_list[0] = inaddr.s_addr;
551 addr_list[1] = (uint32_t) -1;
554 if ((hp = gethostbyname(host)) == NULL) {
555 Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
556 host, gethost_strerror());
560 if (hp->h_length != sizeof(inaddr.s_addr) || hp->h_addrtype != AF_INET) {
561 Qmsg2(jcr, M_ERROR, 0, _("gethostbyname() network address length error.\n\
562 Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
567 for (p = hp->h_addr_list; *p != 0; p++) {
571 addr_list = (uint32_t *)malloc(sizeof(uint32_t) * i);
573 for (p = hp->h_addr_list; *p != 0; p++) {
574 addr_list[i++] = (*(struct in_addr **)p)->s_addr;
576 addr_list[i] = (uint32_t) -1;
583 * Open a TCP connection to the UPS network server
585 * Returns BSOCK * pointer on success
587 * ***FIXME*** implement service from /etc/services
590 bnet_open(JCR *jcr, const char *name, char *host, char *service, int port, int *fatal)
593 struct sockaddr_in tcp_serv_addr; /* socket information */
595 int i, connected = 0;
599 * Fill in the structure serv_addr with the address of
600 * the server that we want to connect with.
602 memset((char *)&tcp_serv_addr, 0, sizeof(tcp_serv_addr));
603 tcp_serv_addr.sin_family = AF_INET;
604 tcp_serv_addr.sin_port = htons(port);
606 if ((addr_list=bget_host_ip(jcr, host)) == NULL) {
611 /* Open a TCP socket */
612 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
619 * Receive notification when connection dies.
621 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
622 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), strerror(errno));
625 for (i = 0; addr_list[i] != ((uint32_t) -1); i++) {
626 /* connect to server */
627 tcp_serv_addr.sin_addr.s_addr = addr_list[i];
628 if (connect(sockfd, (struct sockaddr *)&tcp_serv_addr, sizeof(tcp_serv_addr)) < 0) {
640 return init_bsock(jcr, sockfd, name, host, port, &tcp_serv_addr);
644 * Try to connect to host for max_retry_time at retry_time intervals.
647 bnet_connect(JCR *jcr, int retry_interval, int max_retry_time, const char *name,
648 char *host, char *service, int port, int verbose)
654 for (i=0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL; i -= retry_interval) {
655 if (fatal || (jcr && job_canceled(jcr))) {
658 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
659 name, host, port, strerror(errno));
661 i = 60 * 5; /* complain again in 5 minutes */
663 Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n\
664 Retrying ...\n", name, host, port, strerror(errno));
666 bmicrosleep(retry_interval, 0);
667 max_retry_time -= retry_interval;
668 if (max_retry_time <= 0) {
669 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
670 name, host, port, strerror(errno));
679 * Return the string for the error that occurred
680 * on the socket. Only the first error is retained.
682 char *bnet_strerror(BSOCK *bsock)
684 return strerror(bsock->b_errno);
688 * Format and send a message
689 * Returns: 0 on failure
693 bnet_fsend(BSOCK *bs, const char *fmt, ...)
698 if (bs->errors || bs->terminated) {
701 /* This probably won't work, but we vsnprintf, then if we
702 * get a negative length or a length greater than our buffer
703 * (depending on which library is used), the printf was truncated, so
704 * get a biger buffer and try again.
707 maxlen = sizeof_pool_memory(bs->msg) - 1;
708 va_start(arg_ptr, fmt);
709 bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
711 if (bs->msglen < 0 || bs->msglen >= (maxlen-5)) {
712 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
715 return bnet_send(bs);
719 * Set the network buffer size, suggested size is in size.
720 * Actual size obtained is returned in bs->msglen
722 * Returns: 0 on failure
725 bool bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
727 uint32_t dbuf_size, start_size;
728 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
731 opt = IPTOS_THROUGHPUT;
732 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
738 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
740 start_size = dbuf_size;
741 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size+100)) == NULL) {
742 Qmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
745 if (rw & BNET_SETBUF_READ) {
746 while ((dbuf_size > TAPE_BSIZE) &&
747 (setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
748 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
749 dbuf_size -= TAPE_BSIZE;
751 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
752 if (dbuf_size != start_size) {
753 Qmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
755 if (dbuf_size % TAPE_BSIZE != 0) {
756 Qmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
763 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
765 start_size = dbuf_size;
766 if (rw & BNET_SETBUF_WRITE) {
767 while ((dbuf_size > TAPE_BSIZE) &&
768 (setsockopt(bs->fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
769 Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
770 dbuf_size -= TAPE_BSIZE;
772 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
773 if (dbuf_size != start_size) {
774 Qmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
776 if (dbuf_size % TAPE_BSIZE != 0) {
777 Qmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
782 bs->msglen = dbuf_size;
787 * Send a network "signal" to the other end
788 * This consists of sending a negative packet length
790 * Returns: 0 on failure
793 bool bnet_sig(BSOCK *bs, int sig)
796 return bnet_send(bs);
800 * Convert a network "signal" code into
801 * human readable ASCII.
803 const char *bnet_sig_to_ascii(BSOCK *bs)
806 switch (bs->msglen) {
808 return "BNET_EOD"; /* end of data stream */
810 return "BNET_EOD_POLL";
812 return "BNET_STATUS";
814 return "BNET_TERMINATE"; /* terminate connection */
818 return "BNET_HEARTBEAT";
819 case BNET_HB_RESPONSE:
820 return "BNET_HB_RESPONSE";
822 return "BNET_PROMPT";
824 sprintf(buf, "Unknown sig %d", bs->msglen);
830 /* Initialize internal socket structure.
831 * This probably should be done in net_open
834 init_bsock(JCR *jcr, int sockfd, const char *who, const char *host, int port,
835 struct sockaddr_in *client_addr)
837 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
838 memset(bsock, 0, sizeof(BSOCK));
841 bsock->msg = get_pool_memory(PM_MESSAGE);
842 bsock->errmsg = get_pool_memory(PM_MESSAGE);
843 bsock->who = bstrdup(who);
844 bsock->host = bstrdup(host);
846 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
848 * ****FIXME**** reduce this to a few hours once
849 * heartbeats are implemented
851 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
857 dup_bsock(BSOCK *osock)
859 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
860 memcpy(bsock, osock, sizeof(BSOCK));
861 bsock->msg = get_pool_memory(PM_MESSAGE);
862 bsock->errmsg = get_pool_memory(PM_MESSAGE);
864 bsock->who = bstrdup(osock->who);
867 bsock->host = bstrdup(osock->host);
873 /* Close the network connection */
875 bnet_close(BSOCK *bsock)
879 for ( ; bsock != NULL; bsock = next) {
882 if (bsock->timed_out) {
883 shutdown(bsock->fd, 2); /* discard any pending I/O */
885 socketClose(bsock->fd); /* normal close */
893 term_bsock(BSOCK *bsock)
896 free_pool_memory(bsock->msg);
899 ASSERT(1==0); /* double close */
902 free_pool_memory(bsock->errmsg);
903 bsock->errmsg = NULL;