Skip to content
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

Receiving Entity Not Handling EOF (cancel) PDU Correctly #389

Open
2 tasks done
Chouabunga opened this issue Jun 8, 2023 · 0 comments
Open
2 tasks done

Receiving Entity Not Handling EOF (cancel) PDU Correctly #389

Chouabunga opened this issue Jun 8, 2023 · 0 comments
Labels

Comments

@Chouabunga
Copy link

Checklist (Please check before submitting)

  • I reviewed the Contributing Guide.
  • I performed a cursory search to see if the bug report is relevant, not redundant, nor in conflict with other tickets.

Describe the bug
When 2 entities are transferring a file in Reliable mode, if a Cancel command is sent to the sender entity, there appears to be something broken with the resulting handshaking with the receiver entity, which ultimately does not allow the sender entity to terminate the transaction gracefully.

When the sender receives a Cancel command, it issues an EOF (cancel) PDU to the receiver. Upon receiving this EOF-PDU, the receiver immediately terminates, without any response to the sender. This results in the sender being stuck in a wait-for-EOF-Ack state and only terminating when the inactivity timer is reached.

To Reproduce
Steps to reproduce the behavior:

  1. Start a file transfer between 2 CFDP entities in Reliable mode
  2. Send a Cancel command to the sender entity
  3. Observe that receiver entity immediately terminates the transaction (whereas per the CFDP specification, it should send an EOF-Ack, a FIN PDU, and waiting for the FIN-Ack from the sender before terminating)
  4. Observe that the sender entity does not terminate correctly because it continues to wait for the EOF-Ack from the receiver

Expected behavior

  1. File transfer in Reliable mode started between 2 entities
  2. Cancel command sent to sender entity
  3. Sender entity issues a EOF (cancel) PDU to the receiver entity
  4. Receiver entity issues a EOF-Ack PDU to the sender entity
  5. Receiver entity issues a FIN PDU to the sender entity
  6. Sender entity issues a FIN-Ack PDU to the receiver entity and terminates
  7. Receiver entity terminates upon receiving the FIN-Ack

Code snips
I believe issue is in the CF_CFDP_R2_SubstateRecvEof function logic in cf_cfdp_r.c.

The logic defers sending of the EOF-Ack until after CF_CFDP_R2_SubstateRecvEof runs to completion:
/* always ack the EOF, even if we're not done */
t->state_data.r.r2.eof_cc = FGV(eof->cc, PDU_FLAGS_CC);
t->flags.rx.send_ack = 1; /* defer sending ack to tick handling */

EOF (cancel) PDU then follows a path that eventually results in a call to CF_CFDP_R2_Reset:
if(t->state_data.r.r2.eof_cc==CC_NO_ERROR) {
CF_CFDP_R2_Complete(t, 1); /* CF_CFDP_R2_Complete() will change state */
}
else {
CF_CFDP_R2_Reset(t);
}

Then within CF_CFDP_R2_Reset, the current transaction is already reset and freed.
if((t->state_data.r.sub_state==RECV_WAIT_FOR_FIN_ACK)||(t->state_data.r.r2.eof_cc!=CC_NO_ERROR)||(t->history->cc!=CC_NO_ERROR)||t->flags.rx.canceled) {
CF_CFDP_R1_Reset(t); /* it's done */
}

My fix: added an "else if" section to CF_CFDP_R2_SubstateRecvEof:
else if (t->state_data.r.r2.eof_cc == CF_CFDP_ConditionCode_CANCEL_REQUEST_RECEIVED) {
t->flags.rx.send_fin = 1;
t->history->txn_stat = CF_CFDP_ConditionCode_CANCEL_REQUEST_RECEIVED;
}

System observed on:

  • Hardware
  • OS: Linux Ubuntu 20.04
  • Versions CF 3.0.0
    Additional context
    N/A

Reporter Info
Katie Chou

@chillfig chillfig added the bug label Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants