1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2007-2011 Free Software Foundation Europe e.V.
5 Copyright (C) 2013-2019 Bareos GmbH & Co. KG
6
7 This program is Free Software; you can redistribute it and/or
8 modify it under the terms of version three of the GNU Affero General Public
9 License as published by the Free Software Foundation and included
10 in the file LICENSE.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.
21 */
22 /*
23 * TCP Sockets abstraction.
24 *
25 * Kern Sibbald
26 *
27 * Extracted from other source files by Marco van Wieringen, September 2013.
28 */
29
30 #include "include/bareos.h"
31 #include "include/jcr.h"
32 #include <netdb.h>
33 #include <netinet/tcp.h>
34 #include "lib/bnet.h"
35 #include "lib/bpoll.h"
36 #include "lib/btimers.h"
37 #include "lib/tls_openssl.h"
38 #include "lib/bsock_tcp.h"
39 #include "lib/berrno.h"
40
41 #ifndef ENODATA /* not defined on BSD systems */
42 # define ENODATA EPIPE
43 #endif
44
45 #ifndef SOL_TCP
46 # define SOL_TCP IPPROTO_TCP
47 #endif
48
49 #ifdef HAVE_WIN32
50 # define socketRead(fd, buf, len) ::recv(fd, buf, len, 0)
51 # define socketWrite(fd, buf, len) ::send(fd, buf, len, 0)
52 # define socketClose(fd) ::closesocket(fd)
53 #else
54 # define socketRead(fd, buf, len) ::read(fd, buf, len)
55 # define socketWrite(fd, buf, len) ::write(fd, buf, len)
56 # define socketClose(fd) ::close(fd)
57 #endif
58
BareosSocketTCP()59 BareosSocketTCP::BareosSocketTCP() : BareosSocket() {}
60
~BareosSocketTCP()61 BareosSocketTCP::~BareosSocketTCP() { destroy(); }
62
clone()63 BareosSocket* BareosSocketTCP::clone()
64 {
65 BareosSocketTCP* clone = new BareosSocketTCP(*this);
66
67 /* do not use memory buffer from copied socket */
68 clone->msg = GetPoolMemory(PM_BSOCK);
69 clone->errmsg = GetPoolMemory(PM_MESSAGE);
70
71 if (src_addr) { src_addr = new IPADDR(*(src_addr)); }
72 if (who_) { who_ = strdup(who_); }
73 if (host_) { host_ = strdup(host_); }
74
75 /* duplicate file descriptors */
76 if (fd_ >= 0) { clone->fd_ = dup(fd_); }
77 if (spool_fd_ >= 0) { clone->spool_fd_ = dup(spool_fd_); }
78
79 clone->cloned_ = true;
80
81 return clone;
82 }
83
84 /*
85 * Try to connect to host for max_retry_time at retry_time intervals.
86 * Note, you must have called the constructor prior to calling
87 * this routine.
88 */
connect(JobControlRecord * jcr,int retry_interval,utime_t max_retry_time,utime_t heart_beat,const char * name,const char * host,char * service,int port,bool verbose)89 bool BareosSocketTCP::connect(JobControlRecord* jcr,
90 int retry_interval,
91 utime_t max_retry_time,
92 utime_t heart_beat,
93 const char* name,
94 const char* host,
95 char* service,
96 int port,
97 bool verbose)
98 {
99 bool ok = false;
100 int i;
101 int fatal = 0;
102 time_t begin_time = time(NULL);
103 time_t now;
104 btimer_t* tid = NULL;
105
106 /*
107 * Try to trap out of OS call when time expires
108 */
109 if (max_retry_time) {
110 tid = start_thread_timer(jcr, pthread_self(), (uint32_t)max_retry_time);
111 }
112
113 for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
114 i -= retry_interval) {
115 BErrNo be;
116 if (fatal || (jcr && JobCanceled(jcr))) { goto bail_out; }
117 Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n", name, host, port,
118 be.bstrerror());
119 if (i < 0) {
120 i = 60 * 5; /* complain again in 5 minutes */
121 if (verbose)
122 Qmsg4(jcr, M_WARNING, 0,
123 _("Could not connect to %s on %s:%d. ERR=%s\n"
124 "Retrying ...\n"),
125 name, host, port, be.bstrerror());
126 }
127 Bmicrosleep(retry_interval, 0);
128 now = time(NULL);
129 if (begin_time + max_retry_time <= now) {
130 Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"),
131 name, host, port, be.bstrerror());
132 goto bail_out;
133 }
134 }
135 ok = true;
136
137 bail_out:
138 if (tid) { StopThreadTimer(tid); }
139 return ok;
140 }
141
142 /*
143 * Finish initialization of the pocket structure.
144 */
FinInit(JobControlRecord * jcr,int sockfd,const char * who,const char * host,int port,struct sockaddr * lclient_addr)145 void BareosSocketTCP::FinInit(JobControlRecord* jcr,
146 int sockfd,
147 const char* who,
148 const char* host,
149 int port,
150 struct sockaddr* lclient_addr)
151 {
152 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
153 SetWho(strdup(who));
154 SetHost(strdup(host));
155 SetPort(port);
156 memcpy(&client_addr, lclient_addr, sizeof(client_addr));
157 SetJcr(jcr);
158 }
159
160 /*
161 * Open a TCP connection to the server
162 *
163 * Returns NULL
164 * Returns BareosSocket * pointer on success
165 */
open(JobControlRecord * jcr,const char * name,const char * host,char * service,int port,utime_t heart_beat,int * fatal)166 bool BareosSocketTCP::open(JobControlRecord* jcr,
167 const char* name,
168 const char* host,
169 char* service,
170 int port,
171 utime_t heart_beat,
172 int* fatal)
173 {
174 int sockfd = -1;
175 dlist* addr_list;
176 IPADDR *ipaddr, *next, *to_free;
177 bool connected = false;
178 int value;
179 const char* errstr;
180 int save_errno = 0;
181
182 /*
183 * Fill in the structure serv_addr with the address of
184 * the server that we want to connect with.
185 */
186 if ((addr_list = BnetHost2IpAddrs(host, 0, &errstr)) == NULL) {
187 /*
188 * Note errstr is not malloc'ed
189 */
190 Qmsg2(jcr, M_ERROR, 0,
191 _("BnetHost2IpAddrs() for host \"%s\" failed: ERR=%s\n"), host,
192 errstr);
193 Dmsg2(100, "BnetHost2IpAddrs() for host %s failed: ERR=%s\n", host, errstr);
194 *fatal = 1;
195 return false;
196 }
197
198 /*
199 * Remove any duplicate addresses.
200 */
201 for (ipaddr = (IPADDR*)addr_list->first(); ipaddr;
202 ipaddr = (IPADDR*)addr_list->next(ipaddr)) {
203 next = (IPADDR*)addr_list->next(ipaddr);
204 while (next) {
205 /*
206 * See if the addresses match.
207 */
208 if (ipaddr->GetSockaddrLen() == next->GetSockaddrLen()
209 && memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(),
210 ipaddr->GetSockaddrLen())
211 == 0) {
212 to_free = next;
213 next = (IPADDR*)addr_list->next(next);
214 addr_list->remove(to_free);
215 delete to_free;
216 } else {
217 next = (IPADDR*)addr_list->next(next);
218 }
219 }
220 }
221
222 if (use_keepalive_) {
223 value = 1;
224 } else {
225 value = 0;
226 }
227
228 foreach_dlist (ipaddr, addr_list) {
229 ipaddr->SetPortNet(htons(port));
230 char allbuf[256 * 10];
231 char curbuf[256];
232 Dmsg2(100, "Current %s All %s\n",
233 ipaddr->build_address_str(curbuf, sizeof(curbuf)),
234 BuildAddressesString(addr_list, allbuf, sizeof(allbuf)));
235 /* Open a TCP socket */
236 if ((sockfd = socket(ipaddr->GetFamily(), SOCK_STREAM, 0)) < 0) {
237 BErrNo be;
238 save_errno = errno;
239 switch (errno) {
240 #ifdef EPFNOSUPPORT
241 case EPFNOSUPPORT:
242 /*
243 * The name lookup of the host returned an address in a protocol
244 * family we don't support. Suppress the error and try the next
245 * address.
246 */
247 break;
248 #endif
249 #ifdef EAFNOSUPPORT
250 case EAFNOSUPPORT:
251 /*
252 * The name lookup of the host returned an address in a address family
253 * we don't support. Suppress the error and try the next address.
254 */
255 break;
256 #endif
257 default:
258 *fatal = 1;
259 Pmsg3(000, _("Socket open error. proto=%d port=%d. ERR=%s\n"),
260 ipaddr->GetFamily(), ipaddr->GetPortHostOrder(),
261 be.bstrerror());
262 break;
263 }
264 continue;
265 }
266
267 /*
268 * Bind to the source address if it is set
269 */
270 if (src_addr) {
271 if (bind(sockfd, src_addr->get_sockaddr(), src_addr->GetSockaddrLen())
272 < 0) {
273 BErrNo be;
274 save_errno = errno;
275 *fatal = 1;
276 Pmsg2(000, _("Source address bind error. proto=%d. ERR=%s\n"),
277 src_addr->GetFamily(), be.bstrerror());
278 if (sockfd >= 0) {
279 socketClose(sockfd);
280 sockfd = -1;
281 }
282 continue;
283 }
284 }
285
286 /*
287 * Keep socket from timing out from inactivity
288 */
289 SetKeepalive(jcr, sockfd, use_keepalive_, heart_beat, heart_beat);
290
291 /*
292 * Connect to server
293 */
294 if (::connect(sockfd, ipaddr->get_sockaddr(), ipaddr->GetSockaddrLen())
295 < 0) {
296 save_errno = errno;
297 if (sockfd >= 0) {
298 socketClose(sockfd);
299 sockfd = -1;
300 }
301 continue;
302 }
303 *fatal = 0;
304 connected = true;
305 break;
306 }
307
308 if (!connected) {
309 FreeAddresses(addr_list);
310 errno = save_errno | b_errno_win32;
311 if (sockfd >= 0) {
312 socketClose(sockfd);
313 sockfd = -1;
314 }
315 return false;
316 }
317
318 /*
319 * Keep socket from timing out from inactivity
320 * Do this a second time out of paranoia
321 */
322 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value,
323 sizeof(value))
324 < 0) {
325 BErrNo be;
326 Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"),
327 be.bstrerror());
328 }
329
330 FinInit(jcr, sockfd, name, host, port, ipaddr->get_sockaddr());
331 FreeAddresses(addr_list);
332 fd_ = sockfd;
333 return true;
334 }
335
336
SetKeepalive(JobControlRecord * jcr,int sockfd,bool enable,int keepalive_start,int keepalive_interval)337 bool BareosSocketTCP::SetKeepalive(JobControlRecord* jcr,
338 int sockfd,
339 bool enable,
340 int keepalive_start,
341 int keepalive_interval)
342 {
343 int value = int(enable);
344
345 /*
346 * Keep socket from timing out from inactivity
347 */
348 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&value,
349 sizeof(value))
350 < 0) {
351 BErrNo be;
352 Qmsg1(jcr, M_WARNING, 0, _("Failed to set SO_KEEPALIVE on socket: %s\n"),
353 be.bstrerror());
354 return false;
355 }
356
357 if (enable && keepalive_interval) {
358 #ifdef HAVE_WIN32
359 struct s_tcp_keepalive {
360 u_long onoff;
361 u_long keepalivetime;
362 u_long keepaliveinterval;
363 } val;
364 val.onoff = enable;
365 val.keepalivetime = keepalive_start * 1000L;
366 val.keepaliveinterval = keepalive_interval * 1000L;
367 DWORD got = 0;
368 if (WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, &val, sizeof(val), NULL, 0, &got,
369 NULL, NULL)
370 != 0) {
371 Qmsg1(jcr, M_WARNING, 0,
372 "Failed to set SIO_KEEPALIVE_VALS on socket: %d\n",
373 WSAGetLastError());
374 return false;
375 }
376 #else
377 # if defined(TCP_KEEPIDLE)
378 if (setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE,
379 (sockopt_val_t)&keepalive_start, sizeof(keepalive_start))
380 < 0) {
381 BErrNo be;
382 Qmsg2(jcr, M_WARNING, 0,
383 _("Failed to set TCP_KEEPIDLE = %d on socket: %s\n"),
384 keepalive_start, be.bstrerror());
385 return false;
386 }
387 if (setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL,
388 (sockopt_val_t)&keepalive_interval,
389 sizeof(keepalive_interval))
390 < 0) {
391 BErrNo be;
392 Qmsg2(jcr, M_WARNING, 0,
393 _("Failed to set TCP_KEEPINTVL = %d on socket: %s\n"),
394 keepalive_interval, be.bstrerror());
395 return false;
396 }
397 # endif
398 #endif
399 }
400 return true;
401 }
402
403
SendPacket(int32_t * hdr,int32_t pktsiz)404 bool BareosSocketTCP::SendPacket(int32_t* hdr, int32_t pktsiz)
405 {
406 Enter(400);
407
408 int32_t rc;
409 bool ok = true;
410
411 out_msg_no++; /* increment message number */
412
413 /*
414 * Send data packet
415 */
416 timer_start = watchdog_time; /* start timer */
417 ClearTimedOut();
418
419 /*
420 * Full I/O done in one write
421 */
422 rc = write_nbytes((char*)hdr, pktsiz);
423 timer_start = 0; /* clear timer */
424 if (rc != pktsiz) {
425 errors++;
426 if (errno == 0) {
427 b_errno = EIO;
428 } else {
429 b_errno = errno;
430 }
431 if (rc < 0) {
432 if (!suppress_error_msgs_) {
433 Qmsg5(jcr_, M_ERROR, 0,
434 _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"),
435 message_length, who_, host_, port_, this->bstrerror());
436 }
437 } else {
438 Qmsg5(jcr_, M_ERROR, 0,
439 _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
440 message_length, who_, host_, port_, rc);
441 }
442 ok = false;
443 }
444
445 Leave(400);
446
447 return ok;
448 }
449
450 /*
451 * Send a message over the network. The send consists of
452 * two network packets. The first is sends a 32 bit integer containing
453 * the length of the data packet which follows.
454 *
455 * Returns: false on failure
456 * true on success
457 */
send()458 bool BareosSocketTCP::send()
459 {
460 /*
461 * Send msg (length: message_length).
462 * As send() and recv() uses the same buffer (msg and message_length)
463 * store the original message_length in an own variable,
464 * that will not be modifed by recv().
465 */
466 const int32_t o_msglen = message_length;
467 int32_t pktsiz;
468 int32_t written = 0;
469 int32_t packet_msglen = 0;
470 bool ok = true;
471 /*
472 * Store packet length at head of message -- note, we have reserved an int32_t
473 * just before msg, So we can store there
474 */
475 int32_t* hdr = (int32_t*)(msg - (int)header_length);
476
477 if (errors) {
478 if (!suppress_error_msgs_) {
479 Qmsg4(jcr_, M_ERROR, 0, _("Socket has errors=%d on call to %s:%s:%d\n"),
480 errors, who_, host_, port_);
481 }
482 return false;
483 }
484
485 if (IsTerminated()) {
486 if (!suppress_error_msgs_) {
487 Qmsg4(jcr_, M_ERROR, 0,
488 _("Socket is terminated=%d on call to %s:%s:%d\n"), IsTerminated(),
489 who_, host_, port_);
490 }
491 return false;
492 }
493
494 LockMutex();
495
496 /*
497 * Compute total packet length
498 */
499 if (o_msglen <= 0) {
500 pktsiz = header_length; /* signal, no data */
501 *hdr = htonl(o_msglen); /* store signal */
502 ok = SendPacket(hdr, pktsiz);
503 } else {
504 /*
505 * msg might be to long for a single Bareos packet.
506 * If so, send msg as multiple packages.
507 */
508 while (ok && (written < o_msglen)) {
509 if ((o_msglen - written) > max_message_len) {
510 /*
511 * Message is to large for a single Bareos packet.
512 * Send it via multiple packets.
513 */
514 pktsiz = max_packet_size; /* header + data */
515 packet_msglen = max_message_len;
516 } else {
517 /*
518 * Remaining message fits into one Bareos packet
519 */
520 pktsiz = header_length + (o_msglen - written); /* header + data */
521 packet_msglen = (o_msglen - written);
522 }
523
524 *hdr = htonl(packet_msglen); /* store length */
525 ok = SendPacket(hdr, pktsiz);
526 written += packet_msglen;
527 hdr = (int32_t*)(msg + written - (int)header_length);
528 }
529 }
530
531 UnlockMutex();
532
533 return ok;
534 }
535
536 /*
537 * Receive a message from the other end. Each message consists of
538 * two packets. The first is a header that contains the size
539 * of the data that follows in the second packet.
540 * Returns number of bytes read (may return zero)
541 * Returns -1 on signal (BNET_SIGNAL)
542 * Returns -2 on hard end of file (BNET_HARDEOF)
543 * Returns -3 on error (BNET_ERROR)
544 *
545 * Unfortunately, it is a bit complicated because we have these
546 * four return types:
547 * 1. Normal data
548 * 2. Signal including end of data stream
549 * 3. Hard end of file
550 * 4. Error
551 * Using IsBnetStop() and IsBnetError() you can figure this all out.
552 */
recv()553 int32_t BareosSocketTCP::recv()
554 {
555 int32_t nbytes;
556 int32_t pktsiz;
557
558 msg[0] = 0;
559 message_length = 0;
560 if (errors || IsTerminated()) { return BNET_HARDEOF; }
561
562 if (mutex_) { mutex_->lock(); }
563
564 read_seqno++; /* bump sequence number */
565 timer_start = watchdog_time; /* set start wait time */
566 ClearTimedOut();
567
568 /*
569 * Get data size -- in int32_t
570 */
571 if ((nbytes = read_nbytes((char*)&pktsiz, header_length)) <= 0) {
572 timer_start = 0; /* clear timer */
573 /*
574 * Probably pipe broken because client died
575 */
576 if (errno == 0) {
577 b_errno = ENODATA;
578 } else {
579 b_errno = errno;
580 }
581 errors++;
582 nbytes = BNET_HARDEOF; /* assume hard EOF received */
583 goto get_out;
584 }
585 timer_start = 0; /* clear timer */
586 if (nbytes != header_length) {
587 errors++;
588 b_errno = EIO;
589 Qmsg5(jcr_, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
590 header_length, nbytes, who_, host_, port_);
591 nbytes = BNET_ERROR;
592 goto get_out;
593 }
594
595 pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */
596
597 if (pktsiz == 0) { /* No data transferred */
598 timer_start = 0; /* clear timer */
599 in_msg_no++;
600 message_length = 0;
601 nbytes = 0; /* zero bytes read */
602 goto get_out;
603 }
604
605 /*
606 * If signal or packet size too big
607 */
608 if (pktsiz < 0 || pktsiz > max_packet_size) {
609 if (pktsiz > 0) { /* if packet too big */
610 Qmsg3(jcr_, M_FATAL, 0,
611 _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"),
612 who_, host_, port_);
613 pktsiz = BNET_TERMINATE; /* hang up */
614 }
615 if (pktsiz == BNET_TERMINATE) { SetTerminated(); }
616 timer_start = 0; /* clear timer */
617 b_errno = ENODATA;
618 message_length = pktsiz; /* signal code */
619 nbytes = BNET_SIGNAL; /* signal */
620 goto get_out;
621 }
622
623 /*
624 * Make sure the buffer is big enough + one byte for EOS
625 */
626 if (pktsiz >= (int32_t)SizeofPoolMemory(msg)) {
627 msg = ReallocPoolMemory(msg, pktsiz + 100);
628 }
629
630 timer_start = watchdog_time; /* set start wait time */
631 ClearTimedOut();
632
633 /*
634 * Now read the actual data
635 */
636 if ((nbytes = read_nbytes(msg, pktsiz)) <= 0) {
637 timer_start = 0; /* clear timer */
638 if (errno == 0) {
639 b_errno = ENODATA;
640 } else {
641 b_errno = errno;
642 }
643 errors++;
644 Qmsg4(jcr_, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), who_,
645 host_, port_, this->bstrerror());
646 nbytes = BNET_ERROR;
647 goto get_out;
648 }
649 timer_start = 0; /* clear timer */
650 in_msg_no++;
651 message_length = nbytes;
652 if (nbytes != pktsiz) {
653 b_errno = EIO;
654 errors++;
655 Qmsg5(jcr_, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
656 pktsiz, nbytes, who_, host_, port_);
657 nbytes = BNET_ERROR;
658 goto get_out;
659 }
660
661 /*
662 * Always add a zero by to properly Terminate any string that was send to us.
663 * Note, we ensured above that the buffer is at least one byte longer than
664 * the message length.
665 */
666 msg[nbytes] = 0; /* Terminate in case it is a string */
667
668 /*
669 * The following uses *lots* of resources so turn it on only for serious
670 * debugging.
671 */
672
673 get_out:
674 if (mutex_) { mutex_->unlock(); }
675
676 return nbytes; /* return actual length of message */
677 }
678
GetPeer(char * buf,socklen_t buflen)679 int BareosSocketTCP::GetPeer(char* buf, socklen_t buflen)
680 {
681 #if !defined(HAVE_WIN32)
682 if (peer_addr.sin_family == 0) {
683 socklen_t salen = sizeof(peer_addr);
684 int rval = (getpeername)(fd_, (struct sockaddr*)&peer_addr, &salen);
685 if (rval < 0) return rval;
686 }
687 if (!inet_ntop(peer_addr.sin_family, &peer_addr.sin_addr, buf, buflen))
688 return -1;
689
690 return 0;
691 #else
692 return -1;
693 #endif
694 }
695
696 /*
697 * Set the network buffer size, suggested size is in size.
698 * Actual size obtained is returned in bs->message_length
699 *
700 * Returns: false on failure
701 * true on success
702 */
SetBufferSize(uint32_t size,int rw)703 bool BareosSocketTCP::SetBufferSize(uint32_t size, int rw)
704 {
705 uint32_t dbuf_size, start_size;
706
707 #if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
708 int opt;
709
710 opt = IPTOS_THROUGHPUT;
711 setsockopt(fd_, IPPROTO_IP, IP_TOS, (sockopt_val_t)&opt, sizeof(opt));
712 #endif
713
714 if (size != 0) {
715 dbuf_size = size;
716 } else {
717 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
718 }
719 start_size = dbuf_size;
720 if ((msg = ReallocPoolMemory(msg, dbuf_size + 100)) == NULL) {
721 Qmsg0(get_jcr(), M_FATAL, 0,
722 _("Could not malloc BareosSocket data buffer\n"));
723 return false;
724 }
725
726 /*
727 * If user has not set the size, use the OS default -- i.e. do not
728 * try to set it. This allows sys admins to set the size they
729 * want in the OS, and BAREOS will comply. See bug #1493
730 */
731 if (size == 0) {
732 message_length = dbuf_size;
733 return true;
734 }
735
736 if (rw & BNET_SETBUF_READ) {
737 while ((dbuf_size > TAPE_BSIZE)
738 && (setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, (sockopt_val_t)&dbuf_size,
739 sizeof(dbuf_size))
740 < 0)) {
741 BErrNo be;
742 Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
743 dbuf_size -= TAPE_BSIZE;
744 }
745 Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
746 if (dbuf_size != start_size) {
747 Qmsg1(get_jcr(), M_WARNING, 0,
748 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
749 }
750 }
751 if (size != 0) {
752 dbuf_size = size;
753 } else {
754 dbuf_size = DEFAULT_NETWORK_BUFFER_SIZE;
755 }
756 start_size = dbuf_size;
757 if (rw & BNET_SETBUF_WRITE) {
758 while ((dbuf_size > TAPE_BSIZE)
759 && (setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, (sockopt_val_t)&dbuf_size,
760 sizeof(dbuf_size))
761 < 0)) {
762 BErrNo be;
763 Qmsg1(get_jcr(), M_ERROR, 0, _("sockopt error: %s\n"), be.bstrerror());
764 dbuf_size -= TAPE_BSIZE;
765 }
766 Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
767 if (dbuf_size != start_size) {
768 Qmsg1(get_jcr(), M_WARNING, 0,
769 _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
770 }
771 }
772
773 message_length = dbuf_size;
774 return true;
775 }
776
777 /*
778 * Set socket non-blocking
779 *
780 * Returns previous socket flag
781 */
SetNonblocking()782 int BareosSocketTCP::SetNonblocking()
783 {
784 #ifndef HAVE_WIN32
785 int oflags;
786
787 /*
788 * Get current flags
789 */
790 if ((oflags = fcntl(fd_, F_GETFL, 0)) < 0) {
791 BErrNo be;
792 Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"),
793 be.bstrerror());
794 }
795
796 /*
797 * Set O_NONBLOCK flag
798 */
799 if ((fcntl(fd_, F_SETFL, oflags | O_NONBLOCK)) < 0) {
800 BErrNo be;
801 Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
802 be.bstrerror());
803 }
804
805 blocking_ = 0;
806 return oflags;
807 #else
808 int flags;
809 u_long ioctlArg = 1;
810
811 flags = blocking_;
812 ioctlsocket(fd_, FIONBIO, &ioctlArg);
813 blocking_ = 0;
814
815 return flags;
816 #endif
817 }
818
819 /*
820 * Set socket blocking
821 *
822 * Returns previous socket flags
823 */
SetBlocking()824 int BareosSocketTCP::SetBlocking()
825 {
826 #ifndef HAVE_WIN32
827 int oflags;
828
829 /*
830 * Get current flags
831 */
832 if ((oflags = fcntl(fd_, F_GETFL, 0)) < 0) {
833 BErrNo be;
834 Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_GETFL error. ERR=%s\n"),
835 be.bstrerror());
836 }
837
838 /*
839 * Set O_NONBLOCK flag
840 */
841 if ((fcntl(fd_, F_SETFL, oflags & ~O_NONBLOCK)) < 0) {
842 BErrNo be;
843 Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
844 be.bstrerror());
845 }
846
847 blocking_ = 1;
848 return oflags;
849 #else
850 int flags;
851 u_long ioctlArg = 0;
852
853 flags = blocking_;
854 ioctlsocket(fd_, FIONBIO, &ioctlArg);
855 blocking_ = 1;
856
857 return flags;
858 #endif
859 }
860
861 /*
862 * Restores socket flags
863 */
RestoreBlocking(int flags)864 void BareosSocketTCP::RestoreBlocking(int flags)
865 {
866 #ifndef HAVE_WIN32
867 if ((fcntl(fd_, F_SETFL, flags)) < 0) {
868 BErrNo be;
869 Qmsg1(get_jcr(), M_ABORT, 0, _("fcntl F_SETFL error. ERR=%s\n"),
870 be.bstrerror());
871 }
872
873 blocking_ = (flags & O_NONBLOCK) ? true : false;
874 #else
875 u_long ioctlArg = flags;
876
877 ioctlsocket(fd_, FIONBIO, &ioctlArg);
878 blocking_ = 1;
879 #endif
880 }
881
882 /*
883 * Wait for a specified time for data to appear on
884 * the BareosSocket connection.
885 *
886 * Returns: 1 if data available
887 * 0 if timeout
888 * -1 if error
889 */
WaitData(int sec,int usec)890 int BareosSocketTCP::WaitData(int sec, int usec)
891 {
892 int msec;
893
894 msec = (sec * 1000) + (usec / 1000);
895 switch (WaitForReadableFd(fd_, msec, true)) {
896 case 0:
897 b_errno = 0;
898 return 0;
899 case -1:
900 b_errno = errno;
901 return -1; /* error return */
902 default:
903 b_errno = 0;
904 return 1;
905 }
906 }
907
908 /*
909 * As above, but returns on interrupt
910 */
WaitDataIntr(int sec,int usec)911 int BareosSocketTCP::WaitDataIntr(int sec, int usec)
912 {
913 int msec;
914
915 msec = (sec * 1000) + (usec / 1000);
916 switch (WaitForReadableFd(fd_, msec, false)) {
917 case 0:
918 b_errno = 0;
919 return 0;
920 case -1:
921 b_errno = errno;
922 return -1; /* error return */
923 default:
924 b_errno = 0;
925 return 1;
926 }
927 }
928
929 #ifndef SHUT_RDWR
930 # define SHUT_RDWR 2
931 #endif
932
close()933 void BareosSocketTCP::close()
934 {
935 /* if not cloned */
936 ClearLocking();
937 CloseTlsConnectionAndFreeMemory();
938
939 if (fd_ >= 0) {
940 if (!cloned_) {
941 if (IsTimedOut()) { shutdown(fd_, SHUT_RDWR); }
942 }
943 socketClose(fd_);
944 fd_ = -1;
945 }
946 }
947
destroy()948 void BareosSocketTCP::destroy()
949 {
950 /* if this object is cloned
951 * some memory or file descriptors
952 * are duplicated not just copied */
953
954 if (msg) { /* duplicated */
955 FreePoolMemory(msg);
956 msg = nullptr;
957 }
958 if (errmsg) { /* duplicated */
959 FreePoolMemory(errmsg);
960 errmsg = nullptr;
961 }
962 if (who_) { /* duplicated */
963 free(who_);
964 who_ = nullptr;
965 }
966 if (host_) { /* duplicated */
967 free(host_);
968 host_ = nullptr;
969 }
970 if (src_addr) { /* duplicated */
971 free(src_addr);
972 src_addr = nullptr;
973 }
974 if (fd_ >= 0) { /* duplicated */
975 socketClose(fd_);
976 fd_ = -1;
977 }
978 if (spool_fd_ >= 0) { /* duplicated */
979 socketClose(spool_fd_);
980 spool_fd_ = -1;
981 }
982 }
983
984 /*
985 * Read a nbytes from the network.
986 * It is possible that the total bytes require in several
987 * read requests
988 */
read_nbytes(char * ptr,int32_t nbytes)989 int32_t BareosSocketTCP::read_nbytes(char* ptr, int32_t nbytes)
990 {
991 int32_t nleft, nread;
992
993 #ifdef HAVE_TLS
994 if (tls_conn) { return (tls_conn->TlsBsockReadn(this, ptr, nbytes)); }
995 #endif /* HAVE_TLS */
996
997 nleft = nbytes;
998 while (nleft > 0) {
999 errno = 0;
1000 nread = socketRead(fd_, ptr, nleft);
1001 if (IsTimedOut() || IsTerminated()) { return -1; }
1002
1003 #ifdef HAVE_WIN32
1004 /*
1005 * For Windows, we must simulate Unix errno on a socket error in order to
1006 * handle errors correctly.
1007 */
1008 if (nread == SOCKET_ERROR) {
1009 DWORD err = WSAGetLastError();
1010 nread = -1;
1011 if (err == WSAEINTR) {
1012 errno = EINTR;
1013 } else if (err == WSAEWOULDBLOCK) {
1014 errno = EAGAIN;
1015 } else {
1016 errno = EIO; /* some other error */
1017 }
1018 }
1019 #endif
1020
1021 if (nread == -1) {
1022 if (errno == EINTR) { continue; }
1023 if (errno == EAGAIN) {
1024 Bmicrosleep(0, 20000); /* try again in 20ms */
1025 continue;
1026 }
1027 }
1028
1029 if (nread <= 0) { return -1; /* error, or EOF */ }
1030
1031 nleft -= nread;
1032 ptr += nread;
1033 if (UseBwlimit()) { ControlBwlimit(nread); }
1034 }
1035
1036 return nbytes - nleft; /* return >= 0 */
1037 }
1038
1039 /*
1040 * Write nbytes to the network.
1041 * It may require several writes.
1042 */
write_nbytes(char * ptr,int32_t nbytes)1043 int32_t BareosSocketTCP::write_nbytes(char* ptr, int32_t nbytes)
1044 {
1045 int32_t nleft, nwritten;
1046
1047 if (IsSpooling()) {
1048 nwritten = write(spool_fd_, ptr, nbytes);
1049 if (nwritten != nbytes) {
1050 BErrNo be;
1051 b_errno = errno;
1052 Qmsg1(jcr(), M_FATAL, 0, _("Attr spool write error. ERR=%s\n"),
1053 be.bstrerror());
1054 Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
1055 errno = b_errno;
1056 return -1;
1057 }
1058 return nbytes;
1059 }
1060
1061 if (IsBnetDumpEnabled()) {
1062 bnet_dump_->DumpMessageAndStacktraceToFile(ptr, nbytes);
1063 }
1064
1065 #ifdef HAVE_TLS
1066 if (tls_conn) { return (tls_conn->TlsBsockWriten(this, ptr, nbytes)); }
1067 #endif /* HAVE_TLS */
1068
1069 nleft = nbytes;
1070 while (nleft > 0) {
1071 do {
1072 errno = 0;
1073 nwritten = socketWrite(fd_, ptr, nleft);
1074 if (IsTimedOut() || IsTerminated()) { return -1; }
1075
1076 #ifdef HAVE_WIN32
1077 /*
1078 * For Windows, we must simulate Unix errno on a socket
1079 * error in order to handle errors correctly.
1080 */
1081 if (nwritten == SOCKET_ERROR) {
1082 DWORD err = WSAGetLastError();
1083 nwritten = -1;
1084 if (err == WSAEINTR) {
1085 errno = EINTR;
1086 } else if (err == WSAEWOULDBLOCK) {
1087 errno = EAGAIN;
1088 } else {
1089 errno = EIO; /* some other error */
1090 }
1091 }
1092 #endif
1093
1094 } while (nwritten == -1 && errno == EINTR);
1095
1096 /*
1097 * If connection is non-blocking, we will get EAGAIN, so
1098 * use select()/poll() to keep from consuming all
1099 * the CPU and try again.
1100 */
1101 if (nwritten == -1 && errno == EAGAIN) {
1102 WaitForWritableFd(fd_, 1, false);
1103 continue;
1104 }
1105
1106 if (nwritten <= 0) { return -1; /* error */ }
1107
1108 nleft -= nwritten;
1109 ptr += nwritten;
1110 if (UseBwlimit()) { ControlBwlimit(nwritten); }
1111 }
1112
1113 return nbytes - nleft;
1114 }
1115
ConnectionReceivedTerminateSignal()1116 bool BareosSocketTCP::ConnectionReceivedTerminateSignal()
1117 {
1118 int32_t signal;
1119 SetNonblocking();
1120 bool terminated = false;
1121 if (::recv(fd_, (char*)&signal, 4, MSG_PEEK) == 4) {
1122 signal = ntohl(signal);
1123 if (signal == BNET_TERMINATE) {
1124 SetTerminated();
1125 terminated = true;
1126 }
1127 }
1128 SetBlocking();
1129 return terminated;
1130 }
1131