From 2520ff31a1ce823f0072cbdbed49d76a2cc3ca47 Mon Sep 17 00:00:00 2001 From: Michael Tuexen <tuexen@fh-muenster.de> Date: Wed, 14 Oct 2015 21:06:45 +0200 Subject: [PATCH] Fix the vtag mapping for packets containing chunks with the T-bit set. --- gtests/net/packetdrill/run_packet.c | 30 +++++++++++++++++- .../packetdrill/tests/bsd/sctp/sctp_vtag.pkt | 31 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 gtests/net/packetdrill/tests/bsd/sctp/sctp_vtag.pkt diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 6ac53ba6..b4179cb5 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -578,19 +578,22 @@ static int map_inbound_sctp_packet( struct sctp_init_chunk *init; struct sctp_init_ack_chunk *init_ack; struct sctp_sack_chunk *sack; + struct sctp_abort_chunk *abort; struct sctp_shutdown_chunk *shutdown; struct sctp_ecne_chunk *ecne; struct sctp_cwr_chunk *cwr; + struct sctp_shutdown_complete_chunk *shutdown_complete; struct sctp_i_data_chunk *i_data; u32 local_diff, remote_diff; u16 nr_gap_blocks, nr_dup_tsns, i; + bool mapped_vtag; DEBUGP("live remote initiate tag 0x%08x, script remote initiate tag 0x%08x\n", socket->live.remote_initiate_tag, socket->script.remote_initiate_tag); DEBUGP("live local initiate tag 0x%08x, script local initiate tag 0x%08x\n", socket->live.local_initiate_tag, socket->script.local_initiate_tag); - live_packet->sctp->v_tag = htonl(socket->live.local_initiate_tag); + mapped_vtag = false; for (chunk = sctp_chunks_begin(live_packet, &iter, error); chunk != NULL; chunk = sctp_chunks_next(&iter, error)) { @@ -613,6 +616,7 @@ static int map_inbound_sctp_packet( init->initial_tsn = htonl(ntohl(init->initial_tsn) + remote_diff); /* XXX: Does this work in all cases? */ live_packet->sctp->v_tag = htonl(0); + mapped_vtag = true; if (ntohl(init->initiate_tag) == socket->script.local_initiate_tag) { init->initiate_tag = htonl(socket->live.local_initiate_tag); } @@ -636,6 +640,15 @@ static int map_inbound_sctp_packet( sack->block[i + nr_gap_blocks].tsn = htonl(ntohl(sack->block[i + nr_gap_blocks].tsn) + local_diff); } break; + case SCTP_ABORT_CHUNK_TYPE: + abort = (struct sctp_abort_chunk *)chunk; + if (abort->flags & SCTP_ABORT_CHUNK_T_BIT) { + live_packet->sctp->v_tag = htonl(socket->live.remote_initiate_tag); + } else { + live_packet->sctp->v_tag = htonl(socket->live.local_initiate_tag); + } + mapped_vtag = true; + break; case SCTP_SHUTDOWN_CHUNK_TYPE: shutdown = (struct sctp_shutdown_chunk *)chunk; shutdown->cum_tsn = htonl(ntohl(shutdown->cum_tsn) + local_diff); @@ -648,6 +661,15 @@ static int map_inbound_sctp_packet( cwr = (struct sctp_cwr_chunk *)chunk; cwr->lowest_tsn = htonl(ntohl(cwr->lowest_tsn) + local_diff); break; + case SCTP_SHUTDOWN_COMPLETE_CHUNK_TYPE: + shutdown_complete = (struct sctp_shutdown_complete_chunk *)chunk; + if (shutdown_complete->flags & SCTP_SHUTDOWN_COMPLETE_CHUNK_T_BIT) { + live_packet->sctp->v_tag = htonl(socket->live.remote_initiate_tag); + } else { + live_packet->sctp->v_tag = htonl(socket->live.local_initiate_tag); + } + mapped_vtag = true; + break; case SCTP_I_DATA_CHUNK_TYPE: i_data = (struct sctp_i_data_chunk *)chunk; i_data->tsn = htonl(ntohl(i_data->tsn) + remote_diff); @@ -656,6 +678,12 @@ static int map_inbound_sctp_packet( break; } } + if (!mapped_vtag) { + live_packet->sctp->v_tag = htonl(socket->live.local_initiate_tag); + } + DEBUGP("verification tag of inbound packet: 0x%08x\n", + ntohl(live_packet->sctp->v_tag)); + return STATUS_OK; } diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_vtag.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_vtag.pkt new file mode 100644 index 00000000..297c3ec7 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_vtag.pkt @@ -0,0 +1,31 @@ ++0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3 +// Check the handshake with en empty(!) cookie ++0.0 bind(3, ..., ...) = 0 ++0.0 listen(3, 1) = 0 ++0.0 < sctp(tag=1): INIT[flgs=0, tag=1, a_rwnd=1500, os=1, is=1, tsn=0] ++0.0 > sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=..., os=..., is=..., tsn=10, ...] ++0.1 < sctp: COOKIE_ECHO[flgs=0, len=..., val=...] ++0.0 > sctp: COOKIE_ACK[flgs=0] ++0.0 accept(3, ..., ...) = 4 ++0.0 close(3) = 0 ++0.1 < sctp: SHUTDOWN_COMPLETE[flgs=0] ++0.1 < sctp: SHUTDOWN_COMPLETE[flgs=T] ++0.1 < sctp: ABORT[flgs=0] ++0.1 < sctp: ABORT[flgs=T] +//Send some data. +//+1.0 write(4, ..., 1000) = 1000 +//+0.0 > sctp: DATA[flgs=BE, len=1016, tsn=10, sid=0, ssn=0, ppid=0] +//+0.1 < sctp: SACK[flgs=0, cum_tsn=10, a_rwnd=1500, gaps=[], dups=[]] +//Receive some data +//+1.0 < sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=1, ppid=0] +//+0.0 read(4, ..., 2000) = 1000 +//+0.2 > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]] +//Receive more data, observe delayed SACKi +//+1.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=2, ppid=0] +//+0.0 read(4, ..., 2000) = 1000 +//+0.2 > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]] +//Tear down the association +//+1.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=10] +//+0.0 > sctp: SHUTDOWN_ACK[flgs=0] +//+0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0] ++0.0 close(4) = 0 -- GitLab