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,
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)
50 #define socketRead(fd, buf, len) read(fd, buf, len)
51 #define socketWrite(fd, buf, len) write(fd, buf, len)
56 * Read a nbytes from the network.
57 * It is possible that the total bytes require in several
61 static int32_t read_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
69 nread = socketRead(bsock->fd, ptr, nleft);
70 if (bsock->timed_out || bsock->terminated) {
73 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
75 return nread; /* error, or EOF */
80 return nbytes - nleft; /* return >= 0 */
84 * Write nbytes to the network.
85 * It may require several writes.
88 static int32_t write_nbytes(BSOCK *bsock, char *ptr, int32_t nbytes)
90 int32_t nleft, nwritten;
93 nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd);
94 if (nwritten != nbytes) {
95 Jmsg1(bsock->jcr, M_ERROR, 0, _("Spool write error. ERR=%s\n"), strerror(errno));
96 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
105 nwritten = socketWrite(bsock->fd, ptr, nleft);
106 if (bsock->timed_out || bsock->terminated) {
109 } while (nwritten == -1 && errno == EINTR);
111 * If connection is non-blocking, we will get EAGAIN, so
112 * use select() to keep from consuming all the CPU
115 if (nwritten == -1 && errno == EAGAIN) {
120 FD_SET(bsock->fd, &fdset);
123 select(bsock->fd + 1, NULL, &fdset, NULL, &tv);
127 return nwritten; /* error */
136 * Receive a message from the other end. Each message consists of
137 * two packets. The first is a header that contains the size
138 * of the data that follows in the second packet.
139 * Returns number of bytes read (may return zero)
140 * Returns -1 on signal (BNET_SIGNAL)
141 * Returns -2 on hard end of file (BNET_HARDEOF)
142 * Returns -3 on error (BNET_ERROR)
144 * Unfortunately, it is a bit complicated because we have these
147 * 2. Signal including end of data stream
148 * 3. Hard end of file
150 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
152 int32_t bnet_recv(BSOCK *bsock)
157 ASSERT(bsock != NULL);
158 mp_chr(bsock->msg)[0] = 0;
159 if (bsock->errors || bsock->terminated) {
163 bsock->read_seqno++; /* bump sequence number */
164 bsock->timer_start = watchdog_time; /* set start wait time */
165 bsock->timed_out = 0;
166 /* get data size -- in int32_t */
167 if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
168 bsock->timer_start = 0; /* clear timer */
169 /* probably pipe broken because client died */
171 bsock->b_errno = ENODATA;
173 bsock->b_errno = errno;
176 return BNET_HARDEOF; /* assume hard EOF received */
178 bsock->timer_start = 0; /* clear timer */
179 if (nbytes != sizeof(int32_t)) {
181 bsock->b_errno = EIO;
182 Jmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes,
183 bsock->who, bsock->host, bsock->port);
187 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
189 if (pktsiz == 0) { /* No data transferred */
190 bsock->timer_start = 0; /* clear timer */
193 return 0; /* zero bytes read */
196 /* If signal or packet size too big */
197 if (pktsiz < 0 || pktsiz > 1000000) {
198 if (pktsiz > 0) { /* if packet too big */
199 Jmsg3(bsock->jcr, M_FATAL, 0,
200 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
201 bsock->who, bsock->host, bsock->port);
202 pktsiz = BNET_TERMINATE; /* hang up */
204 if (pktsiz == BNET_TERMINATE) {
205 bsock->terminated = 1;
207 bsock->timer_start = 0; /* clear timer */
208 bsock->b_errno = ENODATA;
209 bsock->msglen = pktsiz; /* signal code */
210 return BNET_SIGNAL; /* signal */
213 /* Make sure the buffer is big enough + one byte for EOS */
214 if (pktsiz >= (int32_t)sizeof_pool_memory(bsock->msg)) {
215 bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100);
218 bsock->timer_start = watchdog_time; /* set start wait time */
219 bsock->timed_out = 0;
220 /* now read the actual data */
221 if ((nbytes = read_nbytes(bsock, mp_chr(bsock->msg), pktsiz)) <= 0) {
222 bsock->timer_start = 0; /* clear timer */
224 bsock->b_errno = ENODATA;
226 bsock->b_errno = errno;
229 Jmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
230 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
233 bsock->timer_start = 0; /* clear timer */
235 bsock->msglen = nbytes;
236 if (nbytes != pktsiz) {
237 bsock->b_errno = EIO;
239 Jmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), pktsiz, nbytes,
240 bsock->who, bsock->host, bsock->port);
243 /* always add a zero by to properly terminate any
244 * string that was send to us. Note, we ensured above that the
245 * buffer is at least one byte longer than the message length.
247 mp_chr(bsock->msg)[nbytes] = 0; /* terminate in case it is a string */
248 sm_check(__FILE__, __LINE__, False);
249 return nbytes; /* return actual length of message */
254 * Return 1 if there are errors on this bsock or it is closed,
255 * i.e. stop communicating on this line.
257 int is_bnet_stop(BSOCK *bsock)
259 return bsock->errors || bsock->terminated;
263 * Return number of errors on socket
265 int is_bnet_error(BSOCK *bsock)
267 return bsock->errors;
271 * Call here after error during closing to suppress error
272 * messages which are due to the other end shutting down too.
275 bnet_suppress_error_messages(BSOCK *bsock, int flag)
277 bsock->suppress_error_msgs = flag;
282 * Transmit spooled data now to a BSOCK
284 int bnet_despool_to_bsock(BSOCK *bsock)
289 rewind(bsock->spool_fd);
290 while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) == sizeof(int32_t)) {
291 bsock->msglen = ntohl(pktsiz);
292 if (bsock->msglen > 0) {
293 if (bsock->msglen > (int32_t)sizeof_pool_memory(bsock->msg)) {
294 bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1);
296 nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd);
297 if (nbytes != (size_t)bsock->msglen) {
298 Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen);
299 Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
305 if (ferror(bsock->spool_fd)) {
306 Jmsg1(bsock->jcr, M_ERROR, 0, _("fread error. ERR=%s\n"), strerror(errno));
314 * Send a message over the network. The send consists of
315 * two network packets. The first is sends a 32 bit integer containing
316 * the length of the data packet which follows.
318 * Returns: 0 on failure
322 bnet_send(BSOCK *bsock)
328 if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
331 msglen = bsock->msglen;
332 pktsiz = htonl((int32_t)bsock->msglen);
333 /* send int32_t containing size of data packet */
334 bsock->timer_start = watchdog_time; /* start timer */
335 bsock->timed_out = 0;
336 rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t));
337 bsock->timer_start = 0; /* clear timer */
338 if (rc != sizeof(int32_t)) {
339 if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */
340 bsock->terminated = 1;
341 return 0; /* ignore any errors */
345 bsock->b_errno = EIO;
347 bsock->b_errno = errno;
350 if (!bsock->suppress_error_msgs && !bsock->timed_out) {
351 Jmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
352 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
355 Jmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
356 bsock->who, bsock->host, bsock->port, bsock->msglen, rc);
361 bsock->out_msg_no++; /* increment message number */
362 if (bsock->msglen <= 0) { /* length only? */
363 return 1; /* yes, no data */
366 /* send data packet */
367 bsock->timer_start = watchdog_time; /* start timer */
368 bsock->timed_out = 0;
369 rc = write_nbytes(bsock, mp_chr(bsock->msg), bsock->msglen);
370 bsock->timer_start = 0; /* clear timer */
371 if (rc != bsock->msglen) {
374 bsock->b_errno = EIO;
376 bsock->b_errno = errno;
379 if (!bsock->suppress_error_msgs) {
380 Jmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending to %s:%s:%d: ERR=%s\n"),
381 bsock->who, bsock->host, bsock->port, bnet_strerror(bsock));
384 Jmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
385 bsock->msglen, bsock->who, bsock->host, bsock->port, rc);
393 * Establish an SSL connection -- server side
394 * Codes that ssl_need and ssl_has can take
395 * BNET_SSL_NONE I cannot do ssl
396 * BNET_SSL_OK I can do ssl, but it is not required on my end
397 * BNET_SSL_REQUIRED ssl is required on my end
400 bnet_ssl_server(BSOCK *bsock, char *password, int ssl_need, int ssl_has)
402 /* Check to see if what we need (ssl_need) corresponds to what he has (ssl_has) */
403 /* The other side expects a response from us */
408 * Establish an SSL connection -- client side
410 int bnet_ssl_client(BSOCK *bsock, char *password, int ssl_need)
412 /* We are the client so we must wait for the server to notify us */
418 * Wait for a specified time for data to appear on
419 * the BSOCK connection.
421 * Returns: 1 if data available
426 bnet_wait_data(BSOCK *bsock, int sec)
432 FD_SET(bsock->fd, &fdset);
436 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
437 case 0: /* timeout */
441 bsock->b_errno = errno;
442 if (errno == EINTR || errno == EAGAIN) {
445 return -1; /* error return */
454 * As above, but returns on interrupt
457 bnet_wait_data_intr(BSOCK *bsock, int sec)
463 FD_SET(bsock->fd, &fdset);
467 switch(select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) {
468 case 0: /* timeout */
472 bsock->b_errno = errno;
473 return -1; /* error return */
481 #ifndef NETDB_INTERNAL
482 #define NETDB_INTERNAL -1 /* See errno. */
484 #ifndef NETDB_SUCCESS
485 #define NETDB_SUCCESS 0 /* No problem. */
487 #ifndef HOST_NOT_FOUND
488 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
491 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
494 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
497 #define NO_DATA 4 /* Valid name, no data record of requested type. */
501 * Get human readable error for gethostbyname()
503 static const char *gethost_strerror()
507 return strerror(errno);
509 return "No problem.";
511 return "Authoritative answer Host not found.";
513 return "Non-authoritative Host not found, or ServerFail.";
515 return "Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.";
517 return "Valid name, no data record of resquested type.";
519 return "Unknown error.";
524 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
527 * Convert a hostname or dotted IP address into
528 * a s_addr. We handle only IPv4.
530 static uint32_t *bget_host_ip(JCR *jcr, char *host)
532 struct in_addr inaddr;
533 uint32_t *addr_list; /* this really should be struct in_addr */
538 if ((inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
539 addr_list = (uint32_t *) malloc(sizeof(uint32_t) * 2);
540 addr_list[0] = inaddr.s_addr;
541 addr_list[1] = (uint32_t) -1;
544 if ((hp = gethostbyname(host)) == NULL) {
545 Jmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n",
546 host, gethost_strerror());
550 if (hp->h_length != sizeof(inaddr.s_addr) || hp->h_addrtype != AF_INET) {
551 Jmsg2(jcr, M_ERROR, 0, _("gethostbyname() network address length error.\n\
552 Wanted %d got %d bytes for s_addr.\n"), sizeof(inaddr.s_addr), hp->h_length);
557 for (p = hp->h_addr_list; *p != 0; p++) {
561 addr_list = (uint32_t *)malloc(sizeof(uint32_t) * i);
563 for (p = hp->h_addr_list; *p != 0; p++) {
564 addr_list[i++] = (*(struct in_addr **)p)->s_addr;
566 addr_list[i] = (uint32_t) -1;
573 * Open a TCP connection to the UPS network server
575 * Returns BSOCK * pointer on success
577 * ***FIXME*** implement service from /etc/services
580 bnet_open(JCR *jcr, const char *name, char *host, char *service, int port, int *fatal)
583 struct sockaddr_in tcp_serv_addr; /* socket information */
585 int i, connected = 0;
589 * Fill in the structure serv_addr with the address of
590 * the server that we want to connect with.
592 memset((char *)&tcp_serv_addr, 0, sizeof(tcp_serv_addr));
593 tcp_serv_addr.sin_family = AF_INET;
594 tcp_serv_addr.sin_port = htons(port);
596 if ((addr_list=bget_host_ip(jcr, host)) == NULL) {
601 /* Open a TCP socket */
602 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
609 * Receive notification when connection dies.
611 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) {
612 Jmsg(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), strerror(errno));
615 for (i = 0; addr_list[i] != ((uint32_t) -1); i++) {
616 /* connect to server */
617 tcp_serv_addr.sin_addr.s_addr = addr_list[i];
618 if (connect(sockfd, (struct sockaddr *)&tcp_serv_addr, sizeof(tcp_serv_addr)) < 0) {
630 return init_bsock(jcr, sockfd, name, host, port, &tcp_serv_addr);
634 * Try to connect to host for max_retry_time at retry_time intervals.
637 bnet_connect(JCR *jcr, int retry_interval, int max_retry_time, const char *name,
638 char *host, char *service, int port, int verbose)
644 for (i=0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL; i -= retry_interval) {
645 if (fatal || (jcr && job_canceled(jcr))) {
648 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n",
649 name, host, port, strerror(errno));
651 i = 60 * 5; /* complain again in 5 minutes */
653 Jmsg(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n\
654 Retrying ...\n", name, host, port, strerror(errno));
656 bmicrosleep(retry_interval, 0);
657 max_retry_time -= retry_interval;
658 if (max_retry_time <= 0) {
659 Jmsg(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
660 name, host, port, strerror(errno));
669 * Return the string for the error that occurred
670 * on the socket. Only the first error is retained.
672 char *bnet_strerror(BSOCK *bsock)
674 return strerror(bsock->b_errno);
678 * Format and send a message
679 * Returns: 0 on failure
683 bnet_fsend(BSOCK *bs, const char *fmt, ...)
688 if (bs->errors || bs->terminated) {
691 /* This probably won't work, but we vsnprintf, then if we
692 * get a negative length or a length greater than our buffer
693 * (depending on which library is used), the printf was truncated, so
694 * get a biger buffer and try again.
697 maxlen = sizeof_pool_memory(bs->msg) - 1;
698 va_start(arg_ptr, fmt);
699 bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
701 if (bs->msglen < 0 || bs->msglen >= maxlen) {
702 bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
705 return bnet_send(bs);
709 * Set the network buffer size, suggested size is in size.
710 * Actual size obtained is returned in bs->msglen
712 * Returns: 0 on failure
715 int bnet_set_buffer_size(BSOCK *bs, uint32_t size, int rw)
717 uint32_t dbuf_size, start_size;
718 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
721 opt = IPTOS_THROUGHPUT;
722 setsockopt(bs->fd, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
728 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
730 start_size = dbuf_size;
731 if ((bs->msg = realloc_pool_memory(bs->msg, dbuf_size+100)) == NULL) {
732 Jmsg0(bs->jcr, M_FATAL, 0, _("Could not malloc BSOCK data buffer\n"));
735 if (rw & BNET_SETBUF_READ) {
736 while ((dbuf_size > TAPE_BSIZE) &&
737 (setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
738 Jmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
739 dbuf_size -= TAPE_BSIZE;
741 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
742 if (dbuf_size != start_size) {
743 Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
745 if (dbuf_size % TAPE_BSIZE != 0) {
746 Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
753 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
755 start_size = dbuf_size;
756 if (rw & BNET_SETBUF_WRITE) {
757 while ((dbuf_size > TAPE_BSIZE) &&
758 (setsockopt(bs->fd, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size, sizeof(dbuf_size)) < 0)) {
759 Jmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), strerror(errno));
760 dbuf_size -= TAPE_BSIZE;
762 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
763 if (dbuf_size != start_size) {
764 Jmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
766 if (dbuf_size % TAPE_BSIZE != 0) {
767 Jmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"),
772 bs->msglen = dbuf_size;
777 * Send a network "signal" to the other end
778 * This consists of sending a negative packet length
780 * Returns: 0 on failure
783 int bnet_sig(BSOCK *bs, int sig)
786 return bnet_send(bs);
790 * Convert a network "signal" code into
791 * human readable ASCII.
793 char *bnet_sig_to_ascii(BSOCK *bs)
796 switch (bs->msglen) {
798 return "BNET_EOD"; /* end of data stream */
800 return "BNET_EOD_POLL";
802 return "BNET_STATUS";
804 return "BNET_TERMINATE"; /* terminate connection */
808 return "BNET_HEARTBEAT";
809 case BNET_HB_RESPONSE:
810 return "BNET_HB_RESPONSE";
812 return "BNET_PROMPT";
814 sprintf(buf, "Unknown sig %d", bs->msglen);
820 /* Initialize internal socket structure.
821 * This probably should be done in net_open
824 init_bsock(JCR *jcr, int sockfd, const char *who, char *host, int port,
825 struct sockaddr_in *client_addr)
827 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
828 memset(bsock, 0, sizeof(BSOCK));
831 bsock->msg = get_pool_memory(PM_MESSAGE);
832 bsock->errmsg = get_pool_memory(PM_MESSAGE);
833 bsock->who = bstrdup(who);
834 bsock->host = bstrdup(host);
836 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
838 * ****FIXME**** reduce this to a few hours once
839 * heartbeats are implemented
841 bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */
847 dup_bsock(BSOCK *osock)
849 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
850 memcpy(bsock, osock, sizeof(BSOCK));
851 bsock->msg = get_pool_memory(PM_MESSAGE);
852 bsock->errmsg = get_pool_memory(PM_MESSAGE);
854 bsock->who = bstrdup(osock->who);
857 bsock->host = bstrdup(osock->host);
863 /* Close the network connection */
865 bnet_close(BSOCK *bsock)
869 for ( ; bsock != NULL; bsock = next) {
872 if (bsock->timed_out) {
873 shutdown(bsock->fd, 2); /* discard any pending I/O */
875 close(bsock->fd); /* normal close */
883 term_bsock(BSOCK *bsock)
886 free_pool_memory(bsock->msg);
889 ASSERT(1==0); /* double close */
892 free_pool_memory(bsock->errmsg);
893 bsock->errmsg = NULL;