2 * Network Utility Routines
6 * Adapted and enhanced for Bacula, originally written
7 * for inclusion in the Apcupsd package
12 Copyright (C) 2000, 2001, 2002 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,
35 extern time_t watchdog_time;
38 #define INADDR_NONE -1
41 #ifndef ENODATA /* not defined on BSD systems */
46 #define socketRead(fd, buf, len) recv(fd, buf, len, 0)
47 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
49 #define socketRead(fd, buf, len) read(fd, buf, len)
50 #define socketWrite(fd, buf, len) write(fd, buf, len)
55 * Read a nbytes from the network.
56 * It is possible that the total bytes require in several
60 static int32_t read_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
68 nread = socketRead(bsock->fd, ptr, nleft);
69 if (bsock->timed_out || bsock->terminated) {
72 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
74 return nread; /* error, or EOF */
79 return nbytes - nleft; /* return >= 0 */
83 * Write nbytes to the network.
84 * It may require several writes.
87 static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
89 int32_t nleft, nwritten;
92 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
93 if (nwritten != nbytes) {
94 Jmsg1(bsock->jcr, M_ERROR, 0, _("Spool write error. ERR=%s\n"), strerror(errno));
95 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
104 nwritten = socketWrite(bsock->fd, ptr, nleft);
105 if (bsock->timed_out || bsock->terminated) {
108 } while (nwritten == -1 && errno == EINTR);
110 * If connection is non-blocking, we will get EAGAIN, so
111 * use select() to keep from consuming all the CPU
114 if (nwritten == -1 && errno == EAGAIN) {
119 FD_SET(bsock->fd, &fdset);
122 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
126 return nwritten; /* error */
135 * Receive a message from the other end. Each message consists of
136 * two packets. The first is a header that contains the size
137 * of the data that follows in the second packet.
138 * Returns number of bytes read (may return zero)
139 * Returns -1 on signal (BNET_SIGNAL)
140 * Returns -2 on hard end of file (BNET_HARDEOF)
141 * Returns -3 on error (BNET_ERROR)
143 * Unfortunately, it is a bit complicated because we have these
146 * 2. Signal including end of data stream
147 * 3. Hard end of file
149 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
151 int32_t bnet_recv(BSOCK *bsock)
156 ASSERT(bsock != NULL);
157 mp_chr(bsock->msg)[0] = 0;
158 if (bsock->errors || bsock->terminated) {
162 bsock->read_seqno++; /* bump sequence number */
163 bsock->timer_start = watchdog_time; /* set start wait time */
164 bsock->timed_out = 0;
165 /* get data size -- in int32_t */
166 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
167 bsock->timer_start = 0; /* clear timer */
168 /* probably pipe broken because client died */
170 bsock->b_errno = ENODATA;
172 bsock->b_errno = errno;
175 return BNET_HARDEOF; /* assume hard EOF received */
177 bsock->timer_start = 0; /* clear timer */
178 if (nbytes != sizeof(int32_t)) {
180 bsock->b_errno = EIO;
181 Jmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes,
182 bsock->who, bsock->host, bsock->port);
186 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
188 if (pktsiz == 0) { /* No data transferred */
189 bsock->timer_start = 0; /* clear timer */
192 return 0; /* zero bytes read */
195 /* If signal or packet size too big */
196 if (pktsiz < 0 || pktsiz > 1000000) {
197 if (pktsiz > 0) { /* if packet too big */
198 Jmsg3(bsock->jcr, M_FATAL, 0,
199 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
200 bsock->who, bsock->host, bsock->port);
201 pktsiz = BNET_TERMINATE; /* hang up */
203 if (pktsiz == BNET_TERMINATE) {
204 bsock->terminated = 1;
206 bsock->timer_start = 0; /* clear timer */
207 bsock->b_errno = ENODATA;
208 bsock->msglen = pktsiz; /* signal code */
209 return BNET_SIGNAL; /* signal */
212 /* Make sure the buffer is big enough + one byte for EOS */
213 if (pktsiz >= (int32_t)sizeof_pool_memory(bsock->msg)) {
214 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
217 bsock->timer_start = watchdog_time; /* set start wait time */
218 bsock->timed_out = 0;
219 /* now read the actual data */
220 if ((nbytes = read_nbytes(bsock, mp_chr(bsock->msg), pktsiz)) <= 0) {
221 bsock->timer_start = 0; /* clear timer */
223 bsock->b_errno = ENODATA;
225 bsock->b_errno = errno;
228 Jmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
229 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
232 bsock->timer_start = 0; /* clear timer */
234 bsock->msglen = nbytes;
235 if (nbytes != pktsiz) {
236 bsock->b_errno = EIO;
238 Jmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes,
239 bsock->who, bsock->host, bsock->port);
242 /* always add a zero by to properly terminate any
243 * string that was send to us. Note, we ensured above that the
244 * buffer is at least one byte longer than the message length.
246 mp_chr(bsock->msg)[nbytes] = 0; /* terminate in case it is a string */
247 sm_check(__FILE__, __LINE__, False);
248 return nbytes; /* return actual length of message */
253 * Return 1 if there are errors on this bsock or it is closed,
254 * i.e. stop communicating on this line.
256 int is_bnet_stop(BSOCK *bsock)
258 return bsock->errors || bsock->terminated;
262 * Return number of errors on socket
264 int is_bnet_error(BSOCK *bsock)
266 return bsock->errors;
270 * Call here after error during closing to suppress error
271 * messages which are due to the other end shutting down too.
274 bnet_suppress_error_messages(BSOCK *bsock, int flag)
276 bsock->suppress_error_msgs = flag;
281 * Transmit spooled data now to a BSOCK
283 int bnet_despool_to_bsock(BSOCK *bsock)
288 rewind(bsock->spool_fd);
289 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) == sizeof(int32_t)) {
290 bsock->msglen = ntohl(pktsiz);
291 if (bsock->msglen > 0) {
292 if (bsock->msglen > (int32_t)sizeof_pool_memory(bsock->msg)) {
293 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
295 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
296 if (nbytes != (size_t)bsock->msglen) {
297 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
298 Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
304 if (ferror(bsock->spool_fd)) {
305 Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
313 * Send a message over the network. The send consists of
314 * two network packets. The first is sends a 32 bit integer containing
315 * the length of the data packet which follows.
317 * Returns: 0 on failure
321 bnet_send(BSOCK *bsock)
327 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
330 msglen = bsock->msglen;
331 pktsiz = htonl((int32_t)bsock->msglen);
332 /* send int32_t containing size of data packet */
333 bsock->timer_start = watchdog_time; /* start timer */
334 bsock->timed_out = 0;
335 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
336 bsock->timer_start = 0; /* clear timer */
337 if (rc != sizeof(int32_t)) {
338 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
339 bsock->terminated = 1;
340 return 0; /* ignore any errors */
344 bsock->b_errno = EIO;
346 bsock->b_errno = errno;
349 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
350 Jmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
351 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
354 Jmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
355 bsock->who, bsock->host, bsock->port, bsock->msglen, rc);
360 bsock->out_msg_no++; /* increment message number */
361 if (bsock->msglen <= 0) { /* length only? */
362 return 1; /* yes, no data */
365 /* send data packet */
366 bsock->timer_start = watchdog_time; /* start timer */
367 bsock->timed_out = 0;
368 rc = write_nbytes(bsock, mp_chr(bsock->msg), bsock->msglen);
369 bsock->timer_start = 0; /* clear timer */
370 if (rc != bsock->msglen) {
373 bsock->b_errno = EIO;
375 bsock->b_errno = errno;
378 if (!bsock->suppress_error_msgs) {
379 Jmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
380 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
383 Jmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
384 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
392 * Establish an SSL connection -- server side
393 * Codes that ssl_need and ssl_has can take
394 * BNET_SSL_NONE I cannot do ssl
395 * BNET_SSL_OK I can do ssl, but it is not required on my end
396 * BNET_SSL_REQUIRED ssl is required on my end
399 bnet_ssl_server(BSOCK *bsock, char *password, int ssl_need, int ssl_has)
401 /* Check to see if what we need (ssl_need) corresponds to what he has (ssl_has) */
402 /* The other side expects a response from us */
407 * Establish an SSL connection -- client side
409 int bnet_ssl_client(BSOCK *bsock, char *password, int ssl_need)
411 /* We are the client so we must wait for the server to notify us */
417 * Wait for a specified time for data to appear on
418 * the BSOCK connection.
420 * Returns: 1 if data available
425 bnet_wait_data(BSOCK *bsock, int sec)
431 FD_SET(bsock->fd, &fdset);
435 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
436 case 0: /* timeout */
440 bsock->b_errno = errno;
441 if (errno == EINTR || errno == EAGAIN) {
444 return -1; /* error return */
453 * As above, but returns on interrupt
456 bnet_wait_data_intr(BSOCK *bsock, int sec)
462 FD_SET(bsock->fd, &fdset);
466 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
467 case 0: /* timeout */
471 bsock->b_errno = errno;
472 return -1; /* error return */
480 #ifndef NETDB_INTERNAL
481 #define NETDB_INTERNAL -1 /* See errno. */
483 #ifndef NETDB_SUCCESS
484 #define NETDB_SUCCESS 0 /* No problem. */
486 #ifndef HOST_NOT_FOUND
487 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
490 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
493 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
496 #define NO_DATA 4 /* Valid name, no data record of requested type. */
500 extern int h_errno; /* On error has one of the above */
503 * Get human readable error for gethostbyname()
505 static char *gethost_strerror()
509 return strerror(errno);
511 return "No problem.";
513 return "Authoritative answer Host not found.";
515 return "Non-authoritative Host not found, or ServerFail.";
517 return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
519 return "Valid name, no data record of resquested type.";
521 return "Unknown error.";
526 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
529 * Convert a hostname or dotted IP address into
530 * a s_addr. We handle only IPv4.
532 static uint32_t *bget_host_ip(JCR *jcr, char *host)
534 struct in_addr inaddr;
535 uint32_t *addr_list; /* this really should be struct in_addr */
540 if ((inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
541 addr_list = (uint32_t *) malloc(sizeof(uint32_t) * 2);
542 addr_list[0] = inaddr.s_addr;
543 addr_list[1] = (uint32_t) -1;
546 if ((hp = gethostbyname(host)) == NULL) {
547 Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
548 host, gethost_strerror());
552 if (hp->h_length != sizeof(inaddr.s_addr) || hp->h_addrtype != AF_INET) {
553 Jmsg2(jcr, M_ERROR, 0, _("gethostbyname() network address length error.\n\
554 Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
559 for (p = hp->h_addr_list; *p != 0; p++) {
563 addr_list = (uint32_t *)malloc(sizeof(uint32_t) * i);
565 for (p = hp->h_addr_list; *p != 0; p++) {
566 addr_list[i++] = (*(struct in_addr **)p)->s_addr;
568 addr_list[i] = (uint32_t) -1;
575 * Open a TCP connection to the UPS network server
577 * Returns BSOCK * pointer on success
579 * ***FIXME*** implement service from /etc/services
582 bnet_open(JCR *jcr, char *name, char *host, char *service, int port, int *fatal)
585 struct sockaddr_in tcp_serv_addr; /* socket information */
587 int i, connected = 0;
591 * Fill in the structure serv_addr with the address of
592 * the server that we want to connect with.
594 memset((char *)&tcp_serv_addr, 0, sizeof(tcp_serv_addr));
595 tcp_serv_addr.sin_family = AF_INET;
596 tcp_serv_addr.sin_port = htons(port);
598 if ((addr_list=bget_host_ip(jcr, host)) == NULL) {
603 /* Open a TCP socket */
604 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
611 * Receive notification when connection dies.
613 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
614 Jmsg(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), strerror(errno));
617 for (i = 0; addr_list[i] != ((uint32_t) -1); i++) {
618 /* connect to server */
619 tcp_serv_addr.sin_addr.s_addr = addr_list[i];
620 if (connect(sockfd, (struct sockaddr *)&tcp_serv_addr, sizeof(tcp_serv_addr)) < 0) {
632 return init_bsock(jcr, sockfd, name, host, port, &tcp_serv_addr);
636 * Try to connect to host for max_retry_time at retry_time intervals.
639 bnet_connect(JCR *jcr, int retry_interval, int max_retry_time, char *name,
640 char *host, char *service, int port, int verbose)
646 for (i=0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL; i -= retry_interval) {
647 if (fatal || (jcr && job_canceled(jcr))) {
650 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
651 name, host, port, strerror(errno));
653 i = 60 * 5; /* complain again in 5 minutes */
655 Jmsg(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n\
656 Retrying ...\n", name, host, port, strerror(errno));
658 bmicrosleep(retry_interval, 0);
659 max_retry_time -= retry_interval;
660 if (max_retry_time <= 0) {
661 Jmsg(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
662 name, host, port, strerror(errno));
671 * Return the string for the error that occurred
672 * on the socket. Only the first error is retained.
674 char *bnet_strerror(BSOCK *bsock)
676 return strerror(bsock->b_errno);
680 * Format and send a message
681 * Returns: 0 on failure
685 bnet_fsend(BSOCK *bs, char *fmt, ...)
690 if (bs->errors || bs->terminated) {
693 /* This probably won't work, but we vsnprintf, then if we
694 * get a negative length or a length greater than our buffer
695 * (depending on which library is used), the printf was truncated, so
696 * get a biger buffer and try again.
699 maxlen = sizeof_pool_memory(bs->msg) - 1;
700 va_start(arg_ptr, fmt);
701 bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
703 if (bs->msglen < 0 || bs->msglen >= maxlen) {
704 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
707 return bnet_send(bs);
711 * Set the network buffer size, suggested size is in size.
712 * Actual size obtained is returned in bs->msglen
714 * Returns: 0 on failure
717 int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
719 uint32_t dbuf_size, start_size;
720 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
723 opt = IPTOS_THROUGHPUT;
724 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
730 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
732 start_size = dbuf_size;
733 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size+100)) == NULL) {
734 Jmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
737 if (rw & BNET_SETBUF_READ) {
738 while ((dbuf_size > TAPE_BSIZE) &&
739 (setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
740 Jmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
741 dbuf_size -= TAPE_BSIZE;
743 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
744 if (dbuf_size != start_size) {
745 Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
747 if (dbuf_size % TAPE_BSIZE != 0) {
748 Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
755 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
757 start_size = dbuf_size;
758 if (rw & BNET_SETBUF_WRITE) {
759 while ((dbuf_size > TAPE_BSIZE) &&
760 (setsockopt(bs->fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
761 Jmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
762 dbuf_size -= TAPE_BSIZE;
764 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
765 if (dbuf_size != start_size) {
766 Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
768 if (dbuf_size % TAPE_BSIZE != 0) {
769 Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
774 bs->msglen = dbuf_size;
779 * Send a network "signal" to the other end
780 * This consists of sending a negative packet length
782 * Returns: 0 on failure
785 int bnet_sig(BSOCK *bs, int sig)
788 return bnet_send(bs);
792 * Convert a network "signal" code into
793 * human readable ASCII.
795 char *bnet_sig_to_ascii(BSOCK *bs)
798 switch (bs->msglen) {
800 return "BNET_EOD"; /* end of data stream */
802 return "BNET_EOD_POLL";
804 return "BNET_STATUS";
806 return "BNET_TERMINATE"; /* terminate connection */
810 return "BNET_HEARTBEAT";
811 case BNET_HB_RESPONSE:
812 return "BNET_HB_RESPONSE";
814 return "BNET_PROMPT";
816 sprintf(buf, "Unknown sig %d", bs->msglen);
822 /* Initialize internal socket structure.
823 * This probably should be done in net_open
826 init_bsock(JCR *jcr, int sockfd, char *who, char *host, int port,
827 struct sockaddr_in *client_addr)
829 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
830 memset(bsock, 0, sizeof(BSOCK));
833 bsock->msg = get_pool_memory(PM_MESSAGE);
834 bsock->errmsg = get_pool_memory(PM_MESSAGE);
835 bsock->who = bstrdup(who);
836 bsock->host = bstrdup(host);
838 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
840 * ****FIXME**** reduce this to a few hours once
841 * heartbeats are implemented
843 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
849 dup_bsock(BSOCK *osock)
851 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
852 memcpy(bsock, osock, sizeof(BSOCK));
853 bsock->msg = get_pool_memory(PM_MESSAGE);
854 bsock->errmsg = get_pool_memory(PM_MESSAGE);
856 bsock->who = bstrdup(osock->who);
859 bsock->host = bstrdup(osock->host);
865 /* Close the network connection */
867 bnet_close(BSOCK *bsock)
871 for ( ; bsock != NULL; bsock = next) {
874 if (bsock->timed_out) {
875 shutdown(bsock->fd, 2); /* discard any pending I/O */
877 close(bsock->fd); /* normal close */
885 term_bsock(BSOCK *bsock)
888 free_pool_memory(bsock->msg);
891 ASSERT(1==0); /* double close */
894 free_pool_memory(bsock->errmsg);
895 bsock->errmsg = NULL;