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