Skip to content

Commit

Permalink
bnet-server-tcp: split up creating+binding and listening
Browse files Browse the repository at this point in the history
Instead of bnetservertcp doing open() + bind() + listen() all on its
own, we instead split it up so that you can give the tcp server some
already prepared sockets.

This can be used for great effect in unit tests, where you can now
1) create the sockets inside the test with port set to 0
2) give those sockets to the tcp server to listen to
3) query the selected (free) port with getsockname
This way you do not have to hardcode any ports inside the unit tests.

This also another step in disentangling the socket code and the bareos
core since you now do not need to read the address/port from the
configuration. Hopefully we can in the future unit tests sockets
without needing full blown config parsers.
  • Loading branch information
sebsura authored and BareosBot committed Feb 5, 2024
1 parent 49ae665 commit 4a327e6
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 103 deletions.
77 changes: 68 additions & 9 deletions core/src/dird/socket_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
Copyright (C) 2014-2023 Bareos GmbH & Co. KG
Copyright (C) 2014-2024 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -50,7 +50,7 @@ static char hello_client[] = "Hello Client %127s calling";

/* Global variables */
static ThreadList thread_list;
static alist<s_sockfd*>* sock_fds = NULL;
static std::atomic<bool> server_running;
static pthread_t tcp_server_tid;
static ConnectionPool* client_connections = NULL;

Expand Down Expand Up @@ -134,10 +134,34 @@ extern "C" void* connect_thread(void* arg)
{
SetJcrInThreadSpecificData(nullptr);

sock_fds = new alist<s_sockfd*>(10, not_owned_by_alist);
BnetThreadServerTcp((dlist<IPADDR>*)arg, sock_fds, thread_list,
HandleConnectionRequest, my_config, &server_state,
UserAgentShutdownCallback, CleanupConnectionPool);
auto bound_sockets = OpenAndBindSockets((dlist<IPADDR>*)arg);
if (bound_sockets.size()) {
server_running = true;
BnetThreadServerTcp(std::move(bound_sockets), thread_list,
HandleConnectionRequest, my_config, &server_state,
UserAgentShutdownCallback, CleanupConnectionPool);

} else {
server_state = BnetServerState::kError;
}

return NULL;
}

extern "C" void* connect_with_bound_thread(void* arg)
{
SetJcrInThreadSpecificData(nullptr);

auto bound_sockets = std::move(*(std::vector<s_sockfd>*)arg);
if (bound_sockets.size()) {
server_running = true;
BnetThreadServerTcp(std::move(bound_sockets), thread_list,
HandleConnectionRequest, my_config, &server_state,
UserAgentShutdownCallback, CleanupConnectionPool);

} else {
server_state = BnetServerState::kError;
}

return NULL;
}
Expand Down Expand Up @@ -182,12 +206,47 @@ bool StartSocketServer(dlist<IPADDR>* addrs)
return true;
}

bool StartSocketServer(std::vector<s_sockfd>&& bound_sockets)
{
int status;

if (client_connections == nullptr) {
client_connections = new ConnectionPool();
}

server_state.store(BnetServerState::kUndefined);

if ((status
= pthread_create(&tcp_server_tid, nullptr, connect_with_bound_thread,
(void*)&bound_sockets))
!= 0) {
BErrNo be;
Emsg1(M_ABORT, 0, T_("Cannot create UA thread: %s\n"),
be.bstrerror(status));
}

int tries = 200; /* consider bind() tries in BnetThreadServerTcp */
int wait_ms = 100;
do {
Bmicrosleep(0, wait_ms * 1000);
if (server_state.load() != BnetServerState::kUndefined) { break; }
} while (--tries);

if (server_state != BnetServerState::kStarted) {
if (client_connections) {
delete (client_connections);
client_connections = nullptr;
}
return false;
}
return true;
}

void StopSocketServer()
{
if (sock_fds) {
if (server_running) {
BnetStopAndWaitForThreadServerTcp(tcp_server_tid);
delete sock_fds;
sock_fds = nullptr;
server_running = false;
}
if (client_connections) {
delete (client_connections);
Expand Down
6 changes: 5 additions & 1 deletion core/src/dird/socket_server.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2018-2021 Bareos GmbH & Co. KG
Copyright (C) 2018-2024 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand All @@ -22,12 +22,16 @@
#ifndef BAREOS_DIRD_SOCKET_SERVER_H_
#define BAREOS_DIRD_SOCKET_SERVER_H_

#include <vector>
#include "lib/bnet_server_tcp.h"

template <typename T> class dlist;
class IPADDR;

namespace directordaemon {

bool StartSocketServer(dlist<IPADDR>* addrs);
bool StartSocketServer(std::vector<s_sockfd>&& bound_sockets);
void StopSocketServer();

} /* namespace directordaemon */
Expand Down
19 changes: 11 additions & 8 deletions core/src/filed/socket_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
BAREOS® - Backup Archiving REcovery Open Sourced
Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
Copyright (C) 2014-2023 Bareos GmbH & Co. KG
Copyright (C) 2014-2024 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -43,7 +43,7 @@ namespace filedaemon {
/* Global variables */
static ThreadList thread_list;
static pthread_t tcp_server_tid;
static alist<s_sockfd*>* sock_fds = nullptr;
static std::atomic<bool> server_running = false;

/**
* Connection request. We accept connections either from the Director or the
Expand Down Expand Up @@ -122,22 +122,25 @@ void StartSocketServer(dlist<IPADDR>* addrs)
Dmsg1(10, "filed: listening on port %d\n", p->GetPortHostOrder());
}

sock_fds = new alist<s_sockfd*>(10, not_owned_by_alist);
BnetThreadServerTcp(addrs, sock_fds, thread_list, HandleConnectionRequest,
my_config, nullptr, UserAgentShutdownCallback);
auto bound_sockets = OpenAndBindSockets(addrs);
if (bound_sockets.size()) {
server_running = true;
BnetThreadServerTcp(std::move(bound_sockets), thread_list,
HandleConnectionRequest, my_config, nullptr,
UserAgentShutdownCallback);
}
}

void StopSocketServer(bool wait)
{
Dmsg0(100, "StopSocketServer\n");
if (sock_fds) {
if (server_running) {
BnetStopAndWaitForThreadServerTcp(tcp_server_tid);
/* before thread_servers terminates,
* it calls cleanup_bnet_thread_server_tcp */
if (wait) {
pthread_join(tcp_server_tid, NULL);
delete (sock_fds);
sock_fds = NULL;
server_running = false;
}
}
}
Expand Down

0 comments on commit 4a327e6

Please sign in to comment.