Skip to content

Fixes #555 : IM0 record not always returned from DCE lookup request due to randomized sequence numbers #556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions src/device/pf_cmrpc.c
Original file line number Diff line number Diff line change
@@ -520,9 +520,11 @@ static int pf_session_allocate (pnet_t * net, pf_session_info_t ** pp_sess)
p_sess->in_use = true;
p_sess->p_ar = NULL;
p_sess->sequence_nmb_send = 0;
p_sess->epm_sequence_nmb = 0;
p_sess->dcontrol_sequence_nmb = UINT32_MAX;
p_sess->ix = ix;
pf_scheduler_init_handle (&p_sess->resend_timeout, "rpc");
pf_scheduler_init_handle (&p_sess->epm_timeout, "rpc-lookup");

/* Set activity UUID. Will be overwritten for incoming requests. */
pf_generate_uuid (
@@ -570,6 +572,7 @@ static void pf_session_release (pnet_t * net, pf_session_info_t * p_sess)
}

pf_scheduler_remove_if_running (net, &p_sess->resend_timeout);
pf_scheduler_remove_if_running (net, &p_sess->epm_timeout);

LOG_DEBUG (
PF_RPC_LOG,
@@ -592,6 +595,22 @@ static void pf_session_release (pnet_t * net, pf_session_info_t * p_sess)
}
}

/**
* @internal
*
* An EPM timeout has occurred.
*
* @param net InOut: The p-net stack instance
* @param arg InOut: The session instance.
* @param current_time In: Time when the EPM timeout function was scheduled
*/
static void pf_session_epm_timeout(pnet_t * net, void * arg, uint32_t current_time)
{
struct pf_session_info * p_session = (struct pf_session_info *)arg;

pf_session_release(net, p_session);
}

/**
* @internal
* Find a session (in use) by its activity UUID.
@@ -3109,6 +3128,7 @@ static int pf_cmrpc_lookup_ind (
lookup_request.udpPort = p_sess->port;
ret = pf_cmrpc_lookup_request (
net,
p_sess,
p_rpc_req,
&lookup_request,
&p_sess->rpc_result,
@@ -4639,6 +4659,10 @@ static int pf_cmrpc_dce_packet (
&uuid_epmap_interface,
sizeof (rpc_req.object_uuid)) == 0)
{
/* Incoming EPM request will cancel timeout */
pf_scheduler_remove_if_running(net, &p_sess->epm_timeout);
pf_scheduler_reset_handle(&p_sess->epm_timeout);

rpc_res.fragment_nmb = 0;
rpc_res.flags.idempotent = false;

@@ -4653,10 +4677,16 @@ static int pf_cmrpc_dce_packet (
&p_sess->out_buf_len);
*p_close_socket = p_sess->from_me;

/* Close session after each EPM request
If future more advanced EPM usage is required, implement a
timeout for closing the session */
p_sess->kill_session = true;
// If the pf_cmrpc_lookup_ind didn't request
// the session to be killed, increment the sequence
// number and start a timeout that will kill the
// session if a request is not received soon enough
if(!p_sess->kill_session)
{
p_sess->epm_sequence_nmb++;
pf_scheduler_add(net, 5000000, pf_session_epm_timeout, (void*) p_sess, &p_sess->epm_timeout);
}

}
else
{
6 changes: 5 additions & 1 deletion src/device/pf_cmrpc_epm.c
Original file line number Diff line number Diff line change
@@ -261,14 +261,15 @@ static int pf_cmrdr_add_pnio_entry (
*/
static int pf_cmrdr_inquiry_read_all_reg_ind (
pnet_t * net,
pf_session_info_t * p_sess,
const pf_rpc_header_t * p_rpc_req,
const pf_rpc_lookup_req_t * p_lookup_req,
pf_rpc_lookup_rsp_t * p_lookup_rsp,
pnet_result_t * p_read_status)
{
int ret = -1;

switch (p_rpc_req->sequence_nmb)
switch (p_sess->epm_sequence_nmb)
{
case 0:
{
@@ -315,6 +316,7 @@ static int pf_cmrdr_inquiry_read_all_reg_ind (
}
break;
default:
p_sess->kill_session = true;
break;
}
return ret;
@@ -335,6 +337,7 @@ static int pf_cmrdr_inquiry_read_all_reg_ind (
*/
int pf_cmrpc_lookup_request (
pnet_t * net,
pf_session_info_t * p_sess,
const pf_rpc_header_t * p_rpc_req,
const pf_rpc_lookup_req_t * p_lookup_req,
pnet_result_t * p_read_status,
@@ -361,6 +364,7 @@ int pf_cmrpc_lookup_request (
case PF_RPC_INQUIRY_READ_ALL_REGISTERED_INTERFACES:
pf_cmrdr_inquiry_read_all_reg_ind (
net,
p_sess,
p_rpc_req,
p_lookup_req,
&lookup_rsp,
1 change: 1 addition & 0 deletions src/device/pf_cmrpc_epm.h
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ extern "C" {
*/
int pf_cmrpc_lookup_request (
pnet_t * net,
pf_session_info_t * p_sess,
const pf_rpc_header_t * p_rpc_req,
const pf_rpc_lookup_req_t * p_lookup_req,
pnet_result_t * p_read_status,
3 changes: 3 additions & 0 deletions src/pf_types.h
Original file line number Diff line number Diff line change
@@ -2078,6 +2078,9 @@ typedef struct pf_session_info
uint32_t dcontrol_sequence_nmb; /* From dcontrol request */
pnet_result_t dcontrol_result;

uint32_t epm_sequence_nmb; /* Counts the sequence number for an EPM request. 0 is the 1st request, 1 is 2nd, etc. */
pf_scheduler_handle_t epm_timeout; /* Timeout EPM requests if they don't receive a response within a certain time limit */

/* This timer is used to handle ccontrol and fragment re-transmissions */
pf_scheduler_handle_t resend_timeout;
uint32_t resend_counter;