/*
handle a request timeout
*/
-static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te,
- struct timeval t, void *private)
+static void nbt_name_socket_timeout(struct tevent_context *ev, struct tevent_timer *te,
+ struct timeval t, void *private_data)
{
- struct nbt_name_request *req = talloc_get_type(private,
+ struct nbt_name_request *req = talloc_get_type(private_data,
struct nbt_name_request);
if (req->num_retries != 0) {
return;
}
+ talloc_steal(req, packet);
+ talloc_steal(req, src);
+ talloc_free(tmp_ctx);
+ nbt_name_socket_handle_response_packet(req, packet, src);
+}
+
+void nbt_name_socket_handle_response_packet(struct nbt_name_request *req,
+ struct nbt_name_packet *packet,
+ struct socket_address *src)
+{
/* if this is a WACK response, this we need to go back to waiting,
but perhaps increase the timeout */
if ((packet->operation & NBT_OPCODE) == NBT_OPCODE_WACK) {
+ uint32_t ttl;
if (req->received_wack || packet->ancount < 1) {
nbt_name_request_destructor(req);
req->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
has received our request */
req->num_retries = 0;
req->received_wack = true;
- /* although there can be a timeout in the packet, w2k3 screws it up,
- so better to set it ourselves */
- req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30);
+ /*
+ * there is a timeout in the packet,
+ * it is 5 + 4 * num_old_addresses
+ *
+ * although w2k3 screws it up
+ * and uses num_old_addresses = 0
+ *
+ * so we better fallback to the maximum
+ * of num_old_addresses = 25 if we got
+ * a timeout of less than 9s (5 + 4*1)
+ * or more than 105s (5 + 4*25).
+ */
+ ttl = packet->answers[0].ttl;
+ if ((ttl < (5 + 4*1)) || (ttl > (5 + 4*25))) {
+ ttl = 5 + 4*25;
+ }
+ req->timeout = ttl;
req->te = event_add_timed(req->nbtsock->event_ctx, req,
timeval_current_ofs(req->timeout, 0),
nbt_name_socket_timeout, req);
- talloc_free(tmp_ctx);
return;
}
/* if we don't want multiple replies then we are done */
if (req->allow_multiple_replies &&
req->num_replies < NBT_MAX_REPLIES) {
- talloc_free(tmp_ctx);
return;
}
req->status = NT_STATUS_OK;
done:
- talloc_free(tmp_ctx);
if (req->async.fn) {
req->async.fn(req);
}
/*
handle fd events on a nbt_name_socket
*/
-static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde,
- uint16_t flags, void *private)
+static void nbt_name_socket_handler(struct tevent_context *ev, struct tevent_fd *fde,
+ uint16_t flags, void *private_data)
{
- struct nbt_name_socket *nbtsock = talloc_get_type(private,
+ struct nbt_name_socket *nbtsock = talloc_get_type(private_data,
struct nbt_name_socket);
if (flags & EVENT_FD_WRITE) {
nbt_name_socket_send(nbtsock);
then operations will use that event context
*/
_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
- struct event_context *event_ctx,
+ struct tevent_context *event_ctx,
struct smb_iconv_convenience *iconv_convenience)
{
struct nbt_name_socket *nbtsock;
_PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock,
void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
struct socket_address *),
- void *private)
+ void *private_data)
{
nbtsock->incoming.handler = handler;
- nbtsock->incoming.private_data = private;
+ nbtsock->incoming.private_data = private_data;
EVENT_FD_READABLE(nbtsock->fde);
return NT_STATUS_OK;
}
+/*
+ setup a handler for unexpected requests
+*/
+NTSTATUS nbt_set_unexpected_handler(struct nbt_name_socket *nbtsock,
+ void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
+ struct socket_address *),
+ void *private_data)
+{
+ nbtsock->unexpected.handler = handler;
+ nbtsock->unexpected.private_data = private_data;
+ EVENT_FD_READABLE(nbtsock->fde);
+ return NT_STATUS_OK;
+}
/*
turn a NBT rcode into a NTSTATUS