Fix concurrency issue between setAddress() and address()
we need to copy the address in an argument, the variable can be
freed at any time.
{
int tls_need = BNET_TLS_NONE;
BSOCK *sd = jcr->store_bsock;
{
int tls_need = BNET_TLS_NONE;
BSOCK *sd = jcr->store_bsock;
/* TLS Requirement for the client */
if (jcr->client->tls_enable) {
/* TLS Requirement for the client */
if (jcr->client->tls_enable) {
/*
* Send Client address to the SD
*/
/*
* Send Client address to the SD
*/
- sd->fsend(clientaddr, jcr->client->address(), jcr->client->FDport, tls_need);
+ sd->fsend(clientaddr, jcr->client->address(buf.addr()), jcr->client->FDport, tls_need);
if (!response(jcr, sd, OKclient, "Client", DISPLAY_ERROR)) {
return false;
}
if (!response(jcr, sd, OKclient, "Client", DISPLAY_ERROR)) {
return false;
}
+char *CLIENT::address(POOLMEM *&buf)
- if (!globals) {
- return client_address;
- }
- if (!globals->SetIPaddress) {
- return client_address;
+ P(globals_mutex);
+ if (!globals || !globals->SetIPaddress) {
+ pm_strcpy(buf, client_address);
+
+ } else {
+ pm_strcpy(buf, globals->SetIPaddress);
- /* TODO: Fix concurrency issue between setAddress() and address()
- * we need to copy the address in an argument, the variable can be
- * freed at any time.
- */
- return globals->SetIPaddress;
+ V(globals_mutex);
+ return buf;
}
void CLIENT::setAddress(char *addr)
}
void CLIENT::setAddress(char *addr)
char ed1[100], ed2[100], ed3[100];
DEVICE *dev;
UAContext *ua = (UAContext *)sock;
char ed1[100], ed2[100], ed3[100];
DEVICE *dev;
UAContext *ua = (UAContext *)sock;
if (res == NULL) {
sendit(sock, _("No %s resource defined\n"), res_to_str(type));
if (res == NULL) {
sendit(sock, _("No %s resource defined\n"), res_to_str(type));
if (!acl_access_ok(ua, Client_ACL, res->res_client.name())) {
break;
}
if (!acl_access_ok(ua, Client_ACL, res->res_client.name())) {
break;
}
+ buf = get_pool_memory(PM_FNAME);
sendit(sock, _("Client: Name=%s Enabled=%d Address=%s FDport=%d MaxJobs=%u NumJobs=%u\n"),
res->res_client.name(), res->res_client.is_enabled(),
sendit(sock, _("Client: Name=%s Enabled=%d Address=%s FDport=%d MaxJobs=%u NumJobs=%u\n"),
res->res_client.name(), res->res_client.is_enabled(),
- res->res_client.address(), res->res_client.FDport,
+ res->res_client.address(buf), res->res_client.FDport,
res->res_client.MaxConcurrentJobs, res->res_client.getNumConcurrentJobs());
res->res_client.MaxConcurrentJobs, res->res_client.getNumConcurrentJobs());
sendit(sock, _(" JobRetention=%s FileRetention=%s AutoPrune=%d\n"),
edit_utime(res->res_client.JobRetention, ed1, sizeof(ed1)),
edit_utime(res->res_client.FileRetention, ed2, sizeof(ed2)),
sendit(sock, _(" JobRetention=%s FileRetention=%s AutoPrune=%d\n"),
edit_utime(res->res_client.JobRetention, ed1, sizeof(ed1)),
edit_utime(res->res_client.FileRetention, ed2, sizeof(ed2)),
if (jcr == NULL) {
return nothing;
}
if (jcr == NULL) {
return nothing;
}
+ ASSERTD(buflen < 255, "buflen must be long enough to hold an ip address");
switch (param[0]) {
case 'f':
if (jcr->fileset) {
switch (param[0]) {
case 'f':
if (jcr->fileset) {
- if (jcr->client && jcr->client->address()) {
- return jcr->client->address();
+ if (jcr->client) {
+ POOL_MEM tmp;
+ jcr->client->address(tmp.addr());
+ bstrncpy(buf, tmp.c_str(), buflen);
+ return buf;
void create_client_globals();
int32_t getNumConcurrentJobs();
void setNumConcurrentJobs(int32_t num);
void create_client_globals();
int32_t getNumConcurrentJobs();
void setNumConcurrentJobs(int32_t num);
+ char *address(POOLMEM *&buf);
void setAddress(char *addr);
bool is_enabled();
void setEnabled(bool val);
void setAddress(char *addr);
bool is_enabled();
void setEnabled(bool val);
if (!is_bsock_open(jcr->file_bsock)) {
char name[MAX_NAME_LENGTH + 100];
if (!is_bsock_open(jcr->file_bsock)) {
char name[MAX_NAME_LENGTH + 100];
if (!fd) {
fd = jcr->file_bsock = new_bsock();
if (!fd) {
fd = jcr->file_bsock = new_bsock();
bstrncat(name, jcr->client->name(), sizeof(name));
fd->set_source_address(director->DIRsrc_addr);
bstrncat(name, jcr->client->name(), sizeof(name));
fd->set_source_address(director->DIRsrc_addr);
- if (!fd->connect(jcr,retry_interval,max_retry_time, heart_beat, name, jcr->client->address(),
- NULL, jcr->client->FDport, verbose)) {
+ if (!fd->connect(jcr,retry_interval,
+ max_retry_time,
+ heart_beat, name,
+ jcr->client->address(buf.addr()),
+ NULL,
+ jcr->client->FDport,
+ verbose)) {
fd->close();
jcr->setJobStatus(JS_ErrorTerminated);
return 0;
fd->close();
jcr->setJobStatus(JS_ErrorTerminated);
return 0;
/* Called from delete_cmd() in ua_cmd.c */
int delete_snapshot(UAContext *ua)
{
/* Called from delete_cmd() in ua_cmd.c */
int delete_snapshot(UAContext *ua)
{
POOLMEM *out;
SNAPSHOT_DBR snapdbr;
CLIENT *client;
POOLMEM *out;
SNAPSHOT_DBR snapdbr;
CLIENT *client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
ua->jcr->client = NULL;
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
ua->jcr->client = NULL;
*/
int list_snapshot(UAContext *ua, alist *snap_list)
{
*/
int list_snapshot(UAContext *ua, alist *snap_list)
{
SNAPSHOT_DBR snap;
POOLMEM *buf;
CLIENT *client;
SNAPSHOT_DBR snap;
POOLMEM *buf;
CLIENT *client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(tmp.addr()), client->FDport);
+
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return 0;
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return 0;
CLIENT *client = NULL;
BSOCK *fd = NULL;
POOLMEM *buf = NULL;
CLIENT *client = NULL;
BSOCK *fd = NULL;
POOLMEM *buf = NULL;
SNAPSHOT_DBR snapdbr;
alist *lst;
intptr_t id;
SNAPSHOT_DBR snapdbr;
alist *lst;
intptr_t id;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(tmp.addr()), client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
free_bsock(ua->jcr->file_bsock);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
free_bsock(ua->jcr->file_bsock);
static int setbwlimit_client(UAContext *ua, CLIENT *client, char *Job, int64_t limit)
{
static int setbwlimit_client(UAContext *ua, CLIENT *client, char *Job, int64_t limit)
{
CLIENT *old_client;
char ed1[50];
if (!client) {
CLIENT *old_client;
char ed1[50];
if (!client) {
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
goto bail_out;
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
goto bail_out;
}
/* MA Bug 6 remove ifdef */
sockaddr_to_ascii(&(ua->UA_sock->client_addr),
}
/* MA Bug 6 remove ifdef */
sockaddr_to_ascii(&(ua->UA_sock->client_addr),
- sizeof(ua->UA_sock->client_addr), addr, sizeof(addr));
- client->setAddress(bstrdup(addr));
+ sizeof(ua->UA_sock->client_addr), addr, sizeof(addr));
+ client->setAddress(addr);
ua->send_msg(_("Client \"%s\" address set to %s\n"),
client->name(), addr);
get_out:
ua->send_msg(_("Client \"%s\" address set to %s\n"),
client->name(), addr);
get_out:
int64_t level, int trace, int hangup, int blowup,
char *options, char *tags)
{
int64_t level, int trace, int hangup, int blowup,
char *options, char *tags)
{
CLIENT *old_client;
BSOCK *fd;
CLIENT *old_client;
BSOCK *fd;
ua->jcr->client = client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
ua->jcr->client = client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
+
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
ua->jcr->client = old_client;
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
ua->jcr->client = old_client;
{
STORE *store, **unique_store;
CLIENT *client, **unique_client;
{
STORE *store, **unique_store;
CLIENT *client, **unique_client;
int i, j, found;
int64_t t=0;
int i, j, found;
int64_t t=0;
while ((client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client))) {
found = 0;
for (j=0; j<i; j++) {
while ((client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client))) {
found = 0;
for (j=0; j<i; j++) {
- if (strcmp(unique_client[j]->address(), client->address()) == 0 &&
+ if (strcmp(unique_client[j]->address(buf1.addr()), client->address(buf2.addr())) == 0 &&
unique_client[j]->FDport == client->FDport) {
found = 1;
break;
unique_client[j]->FDport == client->FDport) {
found = 1;
break;
}
if (!found) {
unique_client[i++] = client;
}
if (!found) {
unique_client[i++] = client;
- Dmsg2(140, "Stuffing: %s:%d\n", client->address(), client->FDport);
+ Dmsg2(140, "Stuffing: %s:%d\n", client->address(buf1.addr()), client->FDport);
JOB *job = NULL;
CLIENT *client = NULL;
FILESET *fileset = NULL;
JOB *job = NULL;
CLIENT *client = NULL;
FILESET *fileset = NULL;
int listing = 0;
char since[MAXSTRING];
JCR *jcr = ua->jcr;
int listing = 0;
char since[MAXSTRING];
JCR *jcr = ua->jcr;
get_level_since_time(ua->jcr, since, sizeof(since));
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
get_level_since_time(ua->jcr, since, sizeof(since));
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- jcr->client->name(), jcr->client->address(), jcr->client->FDport);
+ jcr->client->name(), jcr->client->address(buf.addr()), jcr->client->FDport);
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return 1;
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return 1;
*/
static bool dot_ls_cmd(UAContext *ua, const char *cmd)
{
*/
static bool dot_ls_cmd(UAContext *ua, const char *cmd)
{
CLIENT *client = NULL;
char *path = NULL;
JCR *jcr = ua->jcr;
CLIENT *client = NULL;
char *path = NULL;
JCR *jcr = ua->jcr;
init_jcr_job_record(jcr); // need job
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
init_jcr_job_record(jcr); // need job
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- jcr->client->name(), jcr->client->address(), jcr->client->FDport);
+ jcr->client->name(), jcr->client->address(buf.addr()), jcr->client->FDport);
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
static void do_client_cmd(UAContext *ua, CLIENT *client, const char *cmd)
{
BSOCK *fd;
static void do_client_cmd(UAContext *ua, CLIENT *client, const char *cmd)
{
BSOCK *fd;
/* Connect to File daemon */
ua->jcr->client = client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Connect to File daemon */
ua->jcr->client = client;
/* Try to connect for 15 seconds */
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return;
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return;
bool found=false;
alist *clientlist = NULL;
TmpClient *elt;
bool found=false;
alist *clientlist = NULL;
TmpClient *elt;
if ((i = find_arg_with_value(ua, "address")) >= 0) {
ip = ua->argv[i];
if ((i = find_arg_with_value(ua, "address")) >= 0) {
ip = ua->argv[i];
foreach_res(client, R_CLIENT) {
if (acl_access_client_ok(ua, client->name(), JT_BACKUP_RESTORE)) {
if (ip) {
foreach_res(client, R_CLIENT) {
if (acl_access_client_ok(ua, client->name(), JT_BACKUP_RESTORE)) {
if (ip) {
- elt = new TmpClient(client->name(), client->address());
+ elt = new TmpClient(client->name(), client->address(buf.addr()));
clientlist->append(elt);
} else {
clientlist->append(elt);
} else {
}
CLIENT *client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
if (client) {
}
CLIENT *client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
if (client) {
ua->send_msg("client=%s", client->name());
ua->send_msg("client=%s", client->name());
- ua->send_msg("address=%s", client->address());
+ ua->send_msg("address=%s", client->address(buf.addr()));
ua->send_msg("fdport=%d", client->FDport);
ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1));
ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1));
ua->send_msg("fdport=%d", client->FDport);
ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1));
ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1));
char *store_address, ed1[50];
uint32_t store_port;
uint64_t nb = 50 * 1024 * 1024;
char *store_address, ed1[50];
uint32_t store_port;
uint64_t nb = 50 * 1024 * 1024;
int i = find_arg_with_value(ua, "bytes");
if (i > 0) {
int i = find_arg_with_value(ua, "bytes");
if (i > 0) {
if (!ua->api) {
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
if (!ua->api) {
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
}
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
}
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
{
STORE *store, **unique_store;
CLIENT *client, **unique_client;
{
STORE *store, **unique_store;
CLIENT *client, **unique_client;
continue;
}
for (j=0; j<i; j++) {
continue;
}
for (j=0; j<i; j++) {
- if (strcmp(unique_client[j]->address(), client->address()) == 0 &&
+ if (strcmp(unique_client[j]->address(buf1.addr()), client->address(buf2.addr())) == 0 &&
unique_client[j]->FDport == client->FDport) {
found = true;
break;
unique_client[j]->FDport == client->FDport) {
found = true;
break;
}
if (!found) {
unique_client[i++] = client;
}
if (!found) {
unique_client[i++] = client;
- Dmsg2(40, "Stuffing: %s:%d\n", client->address(), client->FDport);
+ Dmsg2(40, "Stuffing: %s:%d\n", client->address(buf1.addr()), client->FDport);
static void do_client_status(UAContext *ua, CLIENT *client, char *cmd)
{
BSOCK *fd;
static void do_client_status(UAContext *ua, CLIENT *client, char *cmd)
{
BSOCK *fd;
if (!acl_access_client_ok(ua, client->name(), JT_BACKUP_RESTORE)) {
ua->error_msg(_("No authorization for Client \"%s\"\n"), client->name());
if (!acl_access_client_ok(ua, client->name(), JT_BACKUP_RESTORE)) {
ua->error_msg(_("No authorization for Client \"%s\"\n"), client->name());
/* Try to connect for 15 seconds */
if (!ua->api) ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
/* Try to connect for 15 seconds */
if (!ua->api) ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- client->name(), client->address(), client->FDport);
+ client->name(), client->address(buf.addr()), client->FDport);
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->send_msg(_("Failed to connect to Client %s.\n====\n"),
client->name());
if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
ua->send_msg(_("Failed to connect to Client %s.\n====\n"),
client->name());
char *p, *q;
const char *str;
char add[50];
char *p, *q;
const char *str;
char add[50];
- char name[MAX_NAME_LENGTH];
+ char name[MAX_ESCAPE_NAME_LENGTH];
default:
str = NULL;
if (callback != NULL) {
default:
str = NULL;
if (callback != NULL) {
- str = callback(jcr, p, add, sizeof(add));
+ str = callback(jcr, p, name, sizeof(name));