Re: [PATCH 2/2] sctp: COOKIE-ACK should back to where the COOKIE-ECHO came from

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Hi Wei
>
> Wei Yongjun wrote:
>   
>> This patch fixed to send COOKIE-ACK back to where the COOKIE-ECHO
>> came from, and if COOKIE ACK is sent to an UNCONFIRMED address,
>> bundled it with a HEARTBEAT including a nonce. Based on RFC4960:
>>
>>   Section 6.4.  Multi-Homed SCTP Endpoints
>>
>>   An endpoint SHOULD transmit reply chunks (e.g., SACK, HEARTBEAT ACK,
>>   etc.) to the same destination transport address from which it
>>   received the DATA or control chunk to which it is replying.
>>
>>   Section 5.4.  Path Verification:
>>
>>   -  A COOKIE ACK MAY be sent to an UNCONFIRMED address, but it MUST be
>>      bundled with a HEARTBEAT including a nonce.  An implementation
>>      that does NOT support bundling MUST NOT send a COOKIE ACK to an
>>      UNCONFIRMED address.
>>
>> Signed-off-by: Wei Yongjun <yjwei@xxxxxxxxxxxxxx>
>> ---
>>  net/sctp/output.c        |   22 ++++++++++++++++++++++
>>  net/sctp/outqueue.c      |    1 +
>>  net/sctp/sm_make_chunk.c |    3 +++
>>  3 files changed, 26 insertions(+), 0 deletions(-)
>>
>> diff --git a/net/sctp/output.c b/net/sctp/output.c
>> index fad261d..a68a57d 100644
>> --- a/net/sctp/output.c
>> +++ b/net/sctp/output.c
>> @@ -260,6 +260,25 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
>>  	return retval;
>>  }
>>  
>> +/* Try to bundle a HEARTBEAT with the packet. */
>> +static sctp_xmit_t sctp_packet_bundle_hb(struct sctp_packet *pkt,
>> +					 struct sctp_chunk *chunk)
>> +{
>> +	sctp_xmit_t retval = SCTP_XMIT_OK;
>> +
>> +	if (pkt->transport->state == SCTP_UNCONFIRMED &&
>> +	    chunk->chunk_hdr->type == SCTP_CID_COOKIE_ACK) {
>> +		struct sctp_transport *transport = pkt->transport;
>> +		struct sctp_chunk *hb;
>> +
>> +		hb = sctp_make_heartbeat(transport->asoc, transport);
>> +		if (hb)
>> +			retval = sctp_packet_append_chunk(pkt, hb);
>> +	}
>> +
>> +	return retval;
>> +}
>> +
>>  /* Append a chunk to the offered packet reporting back any inability to do
>>   * so.
>>   */
>> @@ -329,6 +348,9 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
>>  	list_add_tail(&chunk->list, &packet->chunk_list);
>>  	packet->size += chunk_len;
>>  	chunk->transport = packet->transport;
>> +
>> +	/* Try to bundle HEARTBEAT chunk */
>> +	retval = sctp_packet_bundle_hb(packet, chunk);
>>     
> Not sure if this is the right place.  Also, this will add the HB after cookie-ACK.
> I am wondering if it should go before.   Seems a more correct thing to do is
> to elicit HB-ACK before any further data might flow over the transport.
>   

I add the HB after cookie-ACK is because that the COOKIE-ECHO on
UNCONFIRMED address must also be bundled with a HEARTBEAT.
If HB is before COOKIE-ECHO, the peer is in CLOSED state and the
HB will be treat as OOTB chunk. And I think COOKIE-ACK need to
do the same thing.


> Also, what about all the HB related things like error counters, timers, etc...
> Seems that we should also do that.
>   

Not sure about that, the first HB may be sent then RTO is expired.
Do this may change the orig HB's action.


> May be we can just cue the HB to the control queue if we are not replying to the
> source of INIT-ACK?
>   

If the state is UNCONFIRMED, the transport should not be the source
of INIT-ACK, since INIT-ACK is sent to the source of INIT, and it should
be in ACTIVE state.


>   
>>  finish:
>>  	return retval;
>>  }
>> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>> index abfc0b8..322ecd1 100644
>> --- a/net/sctp/outqueue.c
>> +++ b/net/sctp/outqueue.c
>> @@ -788,6 +788,7 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
>>  			 */
>>  			if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT &&
>>  			    chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK &&
>> +			    chunk->chunk_hdr->type != SCTP_CID_COOKIE_ACK &&
>>  			    chunk->chunk_hdr->type != SCTP_CID_ASCONF_ACK)
>>  				new_transport = asoc->peer.active_path;
>>  		}
>> diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
>> index 04c45dd..b9f08f0 100644
>> --- a/net/sctp/sm_make_chunk.c
>> +++ b/net/sctp/sm_make_chunk.c
>> @@ -584,6 +584,9 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
>>  	if (retval && chunk)
>>  		retval->transport = chunk->transport;
>>  
>> +	if (retval && !retval->transport)
>> +		retval->dest = chunk->source;
>> +
>>     
> This one is good, but I am thinking that transport assignment may be incorrect.
>  Like I said before, when we are restarting, the transport assigned is from the
> existing association, but the packet is transmitted on the temporary association
> that's about to vanish.  Not sure if this is ok.
>   

It can works, but may be the transport should not be set, the only
thing we should do is set the retval->dest.


>
>   
>>  	return retval;
>>  }
>>  
>>     
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>   
--
To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Networking Development]     [Linux OMAP]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux