2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2007 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 * Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $
42 #define socketRead(fd, buf, len) ::recv(fd, buf, len, 0)
43 #define socketWrite(fd, buf, len) ::send(fd, buf, len, 0)
44 #define socketClose(fd) ::closesocket(fd)
46 #define socketRead(fd, buf, len) ::read(fd, buf, len)
47 #define socketWrite(fd, buf, len) ::write(fd, buf, len)
48 #define socketClose(fd) ::close(fd)
52 * Send a message over the network. The send consists of
53 * two network packets. The first is sends a 32 bit integer containing
54 * the length of the data packet which follows.
56 * Returns: false on failure
65 if (errors || terminated || msglen > 1000000) {
68 /* Compute total packet length */
70 pktsiz = sizeof(pktsiz); /* signal, no data */
72 pktsiz = msglen + sizeof(pktsiz); /* data */
74 /* Store packet length at head of message -- note, we
75 * have reserved an int32_t just before msg, so we can
78 hdr = (int32_t *)(msg - (int)sizeof(pktsiz));
79 *hdr = htonl(msglen); /* store signal/length */
81 out_msg_no++; /* increment message number */
83 /* send data packet */
84 timer_start = watchdog_time; /* start timer */
86 /* Full I/O done in one write */
87 rc = write_nbytes(this, (char *)hdr, pktsiz);
88 timer_start = 0; /* clear timer */
97 if (!suppress_error_msgs) {
98 Qmsg5(m_jcr, M_ERROR, 0,
99 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
101 m_host, m_port, bnet_strerror(this));
104 Qmsg5(m_jcr, M_ERROR, 0,
105 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
106 msglen, m_who, m_host, m_port, rc);
114 * Format and send a message
115 * Returns: false on error
118 bool BSOCK::fsend(const char *fmt, ...)
123 if (errors || terminated) {
126 /* This probably won't work, but we vsnprintf, then if we
127 * get a negative length or a length greater than our buffer
128 * (depending on which library is used), the printf was truncated, so
129 * get a bigger buffer and try again.
132 maxlen = sizeof_pool_memory(msg) - 1;
133 va_start(arg_ptr, fmt);
134 msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr);
136 if (msglen > 0 && msglen < (maxlen - 5)) {
139 msg = realloc_pool_memory(msg, maxlen + maxlen / 2);
145 * Receive a message from the other end. Each message consists of
146 * two packets. The first is a header that contains the size
147 * of the data that follows in the second packet.
148 * Returns number of bytes read (may return zero)
149 * Returns -1 on signal (BNET_SIGNAL)
150 * Returns -2 on hard end of file (BNET_HARDEOF)
151 * Returns -3 on error (BNET_ERROR)
153 * Unfortunately, it is a bit complicated because we have these
156 * 2. Signal including end of data stream
157 * 3. Hard end of file
159 * Using is_bnet_stop() and is_bnet_error() you can figure this all out.
161 int32_t BSOCK::recv()
168 if (errors || terminated) {
172 read_seqno++; /* bump sequence number */
173 timer_start = watchdog_time; /* set start wait time */
175 /* get data size -- in int32_t */
176 if ((nbytes = read_nbytes(this, (char *)&pktsiz, sizeof(int32_t))) <= 0) {
177 timer_start = 0; /* clear timer */
178 /* probably pipe broken because client died */
185 return BNET_HARDEOF; /* assume hard EOF received */
187 timer_start = 0; /* clear timer */
188 if (nbytes != sizeof(int32_t)) {
191 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
192 sizeof(int32_t), nbytes, m_who, m_host, m_port);
196 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
198 if (pktsiz == 0) { /* No data transferred */
199 timer_start = 0; /* clear timer */
202 return 0; /* zero bytes read */
205 /* If signal or packet size too big */
206 if (pktsiz < 0 || pktsiz > 1000000) {
207 if (pktsiz > 0) { /* if packet too big */
208 Qmsg3(m_jcr, M_FATAL, 0,
209 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
210 m_who, m_host, m_port);
211 pktsiz = BNET_TERMINATE; /* hang up */
213 if (pktsiz == BNET_TERMINATE) {
216 timer_start = 0; /* clear timer */
218 msglen = pktsiz; /* signal code */
219 return BNET_SIGNAL; /* signal */
222 /* Make sure the buffer is big enough + one byte for EOS */
223 if (pktsiz >= (int32_t) sizeof_pool_memory(msg)) {
224 msg = realloc_pool_memory(msg, pktsiz + 100);
227 timer_start = watchdog_time; /* set start wait time */
229 /* now read the actual data */
230 if ((nbytes = read_nbytes(this, msg, pktsiz)) <= 0) {
231 timer_start = 0; /* clear timer */
238 Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
239 m_who, m_host, m_port, bnet_strerror(this));
242 timer_start = 0; /* clear timer */
245 if (nbytes != pktsiz) {
248 Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
249 pktsiz, nbytes, m_who, m_host, m_port);
252 /* always add a zero by to properly terminate any
253 * string that was send to us. Note, we ensured above that the
254 * buffer is at least one byte longer than the message length.
256 msg[nbytes] = 0; /* terminate in case it is a string */
257 sm_check(__FILE__, __LINE__, false);
258 return nbytes; /* return actual length of message */
265 bool BSOCK::signal(int signal)
268 if (signal == BNET_TERMINATE) {
269 suppress_error_msgs = true;
279 for (; bsock; bsock = next) {
280 next = bsock->m_next; /* get possible pointer to next before destoryed */
283 /* Shutdown tls cleanly. */
285 tls_bsock_shutdown(bsock);
286 free_tls_connection(bsock->tls);
289 #endif /* HAVE_TLS */
290 if (bsock->timed_out) {
291 shutdown(bsock->fd, 2); /* discard any pending I/O */
293 socketClose(bsock->fd); /* normal close */
295 destroy(); /* free the packet */
300 void BSOCK::destroy()
303 free_pool_memory(msg);
306 ASSERT(1 == 0); /* double close */
309 free_pool_memory(errmsg);