mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
r5117: used a composite function to add 4 stage name registration. We send 3
broadcast name registration demands per name per interface at 1 second intervals, then send a name overwrite request and demand. Any name conflict replies are reported. (This used to be commit d656fba6f1a2e9d8c03893741327e5fb59c5271e)
This commit is contained in:
parent
5269fb13a9
commit
5e6082b4b0
@ -151,6 +151,7 @@ struct nbt_name_socket;
|
||||
struct nbt_name_query;
|
||||
struct nbt_name_status;
|
||||
struct nbt_name_register;
|
||||
struct nbt_name_register_bcast;
|
||||
|
||||
struct messaging_context;
|
||||
struct stream_connection;
|
||||
|
@ -11,14 +11,18 @@ ADD_OBJ_FILES = libcli/util/asn1.o \
|
||||
ADD_OBJ_FILES = libcli/util/clilsa.o
|
||||
REQUIRED_SUBSYSTEMS = RPC_NDR_LSA
|
||||
|
||||
[SUBSYSTEM::LIBCLI_COMPOSITE_BASE]
|
||||
ADD_OBJ_FILES = \
|
||||
libcli/composite/composite.o
|
||||
|
||||
[SUBSYSTEM::LIBCLI_COMPOSITE]
|
||||
ADD_OBJ_FILES = \
|
||||
libcli/composite/composite.o \
|
||||
libcli/composite/loadfile.o \
|
||||
libcli/composite/savefile.o \
|
||||
libcli/composite/connect.o \
|
||||
libcli/composite/sesssetup.o \
|
||||
libcli/composite/fetchfile.o
|
||||
REQUIRED_SUBSYSTEMS = LIBCLI_COMPOSITE_BASE
|
||||
|
||||
[SUBSYSTEM::LIBCLI_NBT]
|
||||
ADD_OBJ_FILES = \
|
||||
@ -26,7 +30,7 @@ ADD_OBJ_FILES = \
|
||||
libcli/nbt/nbtsocket.o \
|
||||
libcli/nbt/namequery.o \
|
||||
libcli/nbt/nameregister.o
|
||||
REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET
|
||||
REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE
|
||||
|
||||
[SUBSYSTEM::LIBCLI_RESOLVE]
|
||||
ADD_OBJ_FILES = \
|
||||
|
@ -151,3 +151,14 @@ struct nbt_name_register {
|
||||
uint8_t rcode;
|
||||
} out;
|
||||
};
|
||||
|
||||
/* a send 3 times then demand name broadcast name registration */
|
||||
struct nbt_name_register_bcast {
|
||||
struct {
|
||||
struct nbt_name name;
|
||||
const char *dest_addr;
|
||||
const char *address;
|
||||
uint16_t nb_flags;
|
||||
uint32_t ttl;
|
||||
} in;
|
||||
};
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "libcli/nbt/libnbt.h"
|
||||
#include "libcli/raw/libcliraw.h"
|
||||
#include "libcli/composite/composite.h"
|
||||
#include "system/network.h"
|
||||
|
||||
/*
|
||||
@ -138,3 +140,135 @@ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock,
|
||||
struct nbt_name_request *req = nbt_name_register_send(nbtsock, io);
|
||||
return nbt_name_register_recv(req, mem_ctx, io);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
a 4 step broadcast registration. 3 lots of name registration requests, followed by
|
||||
a name registration demand
|
||||
*/
|
||||
struct register_bcast_state {
|
||||
struct nbt_name_socket *nbtsock;
|
||||
struct nbt_name_register *io;
|
||||
int num_sends;
|
||||
struct nbt_name_request *req;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
state handler for 4 stage name registration
|
||||
*/
|
||||
static void name_register_handler(struct nbt_name_request *req)
|
||||
{
|
||||
struct smbcli_composite *c = talloc_get_type(req->async.private, struct smbcli_composite);
|
||||
struct register_bcast_state *state = talloc_get_type(c->private, struct register_bcast_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = nbt_name_register_recv(state->req, state, state->io);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
/* the registration timed out - good, send the next one */
|
||||
state->num_sends++;
|
||||
if (state->num_sends == 4) {
|
||||
/* all done */
|
||||
c->state = SMBCLI_REQUEST_DONE;
|
||||
c->status = NT_STATUS_OK;
|
||||
goto done;
|
||||
}
|
||||
if (state->num_sends == 3) {
|
||||
state->io->in.register_demand = True;
|
||||
}
|
||||
state->req = nbt_name_register_send(state->nbtsock, state->io);
|
||||
if (state->req == NULL) {
|
||||
c->state = SMBCLI_REQUEST_ERROR;
|
||||
c->status = NT_STATUS_NO_MEMORY;
|
||||
} else {
|
||||
state->req->async.fn = name_register_handler;
|
||||
state->req->async.private = c;
|
||||
}
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
c->state = SMBCLI_REQUEST_ERROR;
|
||||
c->status = status;
|
||||
} else {
|
||||
c->state = SMBCLI_REQUEST_ERROR;
|
||||
c->status = NT_STATUS_CONFLICTING_ADDRESSES;
|
||||
DEBUG(3,("Name registration conflict from %s for %s<%02x> with ip %s - rcode %d\n",
|
||||
state->io->out.reply_from,
|
||||
state->io->out.name.name,
|
||||
state->io->out.name.type,
|
||||
state->io->out.reply_addr,
|
||||
state->io->out.rcode));
|
||||
}
|
||||
|
||||
done:
|
||||
if (c->state >= SMBCLI_REQUEST_DONE &&
|
||||
c->async.fn) {
|
||||
c->async.fn(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
the async send call for a 4 stage name registration
|
||||
*/
|
||||
struct smbcli_composite *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock,
|
||||
struct nbt_name_register_bcast *io)
|
||||
{
|
||||
struct smbcli_composite *c;
|
||||
struct register_bcast_state *state;
|
||||
|
||||
c = talloc_zero(nbtsock, struct smbcli_composite);
|
||||
if (c == NULL) goto failed;
|
||||
|
||||
state = talloc(c, struct register_bcast_state);
|
||||
if (state == NULL) goto failed;
|
||||
|
||||
state->io = talloc(state, struct nbt_name_register);
|
||||
if (state->io == NULL) goto failed;
|
||||
|
||||
state->io->in.name = io->in.name;
|
||||
state->io->in.dest_addr = io->in.dest_addr;
|
||||
state->io->in.address = io->in.address;
|
||||
state->io->in.nb_flags = io->in.nb_flags;
|
||||
state->io->in.register_demand = False;
|
||||
state->io->in.broadcast = True;
|
||||
state->io->in.ttl = io->in.ttl;
|
||||
state->io->in.timeout = 1;
|
||||
|
||||
state->num_sends = 0;
|
||||
state->nbtsock = nbtsock;
|
||||
|
||||
state->req = nbt_name_register_send(nbtsock, state->io);
|
||||
if (state->req == NULL) goto failed;
|
||||
|
||||
state->req->async.fn = name_register_handler;
|
||||
state->req->async.private = c;
|
||||
|
||||
c->private = state;
|
||||
c->state = SMBCLI_REQUEST_SEND;
|
||||
c->event_ctx = nbtsock->event_ctx;
|
||||
|
||||
return c;
|
||||
|
||||
failed:
|
||||
talloc_free(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
broadcast 4 part name register - recv
|
||||
*/
|
||||
NTSTATUS nbt_name_register_bcast_recv(struct smbcli_composite *c)
|
||||
{
|
||||
NTSTATUS status;
|
||||
status = smb_composite_wait(c);
|
||||
talloc_free(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
broadcast 4 part name register - sync interface
|
||||
*/
|
||||
NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock,
|
||||
struct nbt_name_register_bcast *io)
|
||||
{
|
||||
struct smbcli_composite *c = nbt_name_register_bcast_send(nbtsock, io);
|
||||
return nbt_name_register_bcast_recv(c);
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "includes.h"
|
||||
#include "dlinklist.h"
|
||||
#include "nbt_server/nbt_server.h"
|
||||
#include "libcli/raw/libcliraw.h"
|
||||
#include "libcli/composite/composite.h"
|
||||
|
||||
/*
|
||||
start a timer to refresh this name
|
||||
@ -35,14 +37,13 @@ static void nbt_start_refresh_timer(struct nbt_iface_name *iname)
|
||||
/*
|
||||
a name registration has completed
|
||||
*/
|
||||
static void nbt_register_handler(struct nbt_name_request *req)
|
||||
static void nbt_register_handler(struct smbcli_composite *req)
|
||||
{
|
||||
struct nbt_iface_name *iname = talloc_get_type(req->async.private, struct nbt_iface_name);
|
||||
NTSTATUS status;
|
||||
struct nbt_name_register io;
|
||||
|
||||
status = nbt_name_register_recv(req, iname, &io);
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
status = nbt_name_register_bcast_recv(req);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/* good - nobody complained about our registration */
|
||||
iname->nb_flags |= NBT_NM_ACTIVE;
|
||||
DEBUG(3,("Registered %s<%02x> on interface %s\n",
|
||||
@ -51,19 +52,12 @@ static void nbt_register_handler(struct nbt_name_request *req)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n",
|
||||
iname->name.name, iname->name.type, iname->iface->bcast_address,
|
||||
nt_errstr(status)));
|
||||
return;
|
||||
}
|
||||
|
||||
/* someone must have replied with an objection! */
|
||||
iname->nb_flags |= NBT_NM_CONFLICT;
|
||||
|
||||
DEBUG(1,("Name conflict registering %s<%02x> on interface %s - rcode %d from %s for %s\n",
|
||||
|
||||
DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n",
|
||||
iname->name.name, iname->name.type, iname->iface->bcast_address,
|
||||
io.out.rcode, io.out.reply_from, io.out.reply_addr));
|
||||
nt_errstr(status)));
|
||||
}
|
||||
|
||||
|
||||
@ -76,8 +70,8 @@ static void nbt_register_name_iface(struct nbt_interface *iface,
|
||||
{
|
||||
struct nbt_iface_name *iname;
|
||||
const char *scope = lp_netbios_scope();
|
||||
struct nbt_name_register io;
|
||||
struct nbt_name_request *req;
|
||||
struct nbt_name_register_bcast io;
|
||||
struct smbcli_composite *req;
|
||||
|
||||
iname = talloc(iface, struct nbt_iface_name);
|
||||
if (!iname) return;
|
||||
@ -108,12 +102,9 @@ static void nbt_register_name_iface(struct nbt_interface *iface,
|
||||
io.in.dest_addr = iface->bcast_address;
|
||||
io.in.address = iface->ip_address;
|
||||
io.in.nb_flags = nb_flags;
|
||||
io.in.register_demand = False;
|
||||
io.in.broadcast = True;
|
||||
io.in.ttl = iname->ttl;
|
||||
io.in.timeout = 1;
|
||||
|
||||
req = nbt_name_register_send(iface->nbtsock, &io);
|
||||
req = nbt_name_register_bcast_send(iface->nbtsock, &io);
|
||||
if (req == NULL) return;
|
||||
|
||||
req->async.fn = nbt_register_handler;
|
||||
|
Loading…
x
Reference in New Issue
Block a user