diff options
author | tuexen <tuexen@FreeBSD.org> | 2011-08-03 20:21:00 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2011-08-03 20:21:00 +0000 |
commit | f47c615e88590b29d88403fce2ef7e0e28e8ecb3 (patch) | |
tree | 6202f1b3524e68a30395d3b510eebc5a90fa3068 /sys/netinet/sctp_asconf.c | |
parent | 9654d8888d412ad356d2b05a0c6e1be510a21ee9 (diff) | |
download | FreeBSD-src-f47c615e88590b29d88403fce2ef7e0e28e8ecb3.zip FreeBSD-src-f47c615e88590b29d88403fce2ef7e0e28e8ecb3.tar.gz |
The result of a joint work between rrs@ and myself at the IETF:
* Decouple the path supervision using a separate HB timer per path.
* Add support for potentially failed state.
* Bring back RTO.min to 1 second.
* Accept packets on IP-addresses already announced via an ASCONF
* While there: do some cleanups.
Approved by: re@
MFC after: 2 months.
Diffstat (limited to 'sys/netinet/sctp_asconf.c')
-rw-r--r-- | sys/netinet/sctp_asconf.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index a6db580..69f9cf1 100644 --- a/sys/netinet/sctp_asconf.c +++ b/sys/netinet/sctp_asconf.c @@ -198,8 +198,9 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv, static struct mbuf * sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph, - struct sctp_tcb *stcb, int response_required) + struct sctp_tcb *stcb, int send_hb, int response_required) { + struct sctp_nets *net; struct mbuf *m_reply = NULL; struct sockaddr_storage sa_source, sa_store; struct sctp_paramhdr *ph; @@ -284,7 +285,7 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph, SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa); } /* add the address */ - if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, + if (sctp_add_remote_addr(stcb, sa, &net, SCTP_DONOT_SETSCOPE, SCTP_ADDR_DYNAMIC_ADDED) != 0) { SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: error adding address\n"); @@ -298,10 +299,12 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph, m_reply = sctp_asconf_success_response(aph->correlation_id); } - sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, - NULL, SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1); + sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net); sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, - stcb, NULL); + stcb, net); + if (send_hb) { + sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED); + } } return m_reply; } @@ -554,7 +557,12 @@ sctp_process_asconf_set_primary(struct mbuf *m, "process_asconf_set_primary: primary address set\n"); /* notify upper layer */ sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED); - + if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) && + (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) && + (stcb->asoc.alternate)) { + sctp_free_remote_addr(stcb->asoc.alternate); + stcb->asoc.alternate = NULL; + } if (response_required) { m_reply = sctp_asconf_success_response(aph->correlation_id); } @@ -622,7 +630,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset, struct sctp_asconf_ack_chunk *ack_cp; struct sctp_asconf_paramhdr *aph, *ack_aph; struct sctp_ipv6addr_param *p_addr; - unsigned int asconf_limit; + unsigned int asconf_limit, cnt; int error = 0; /* did an error occur? */ /* asconf param buffer */ @@ -717,6 +725,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset, goto send_reply; } /* process through all parameters */ + cnt = 0; while (aph != NULL) { unsigned int param_length, param_type; @@ -749,7 +758,8 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset, case SCTP_ADD_IP_ADDRESS: asoc->peer_supports_asconf = 1; m_result = sctp_process_asconf_add_ip(m, aph, stcb, - error); + (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error); + cnt++; break; case SCTP_DEL_IP_ADDRESS: asoc->peer_supports_asconf = 1; @@ -1959,7 +1969,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int status; - if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 && + if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 || sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { /* subset bound, no ASCONF allowed case, so ignore */ return; @@ -2075,8 +2085,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, stcb->asoc.primary_destination); #else - sctp_send_asconf(stcb, stcb->asoc.primary_destination, - addr_locked); + sctp_send_asconf(stcb, NULL, addr_locked); #endif } } @@ -2328,8 +2337,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * If we have queued params in the open state, send out an ASCONF. */ if (num_queued > 0) { - sctp_send_asconf(stcb, stcb->asoc.primary_destination, - SCTP_ADDR_NOT_LOCKED); + sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED); } } @@ -2384,8 +2392,7 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa) stcb->sctp_ep, stcb, stcb->asoc.primary_destination); #else - sctp_send_asconf(stcb, stcb->asoc.primary_destination, - SCTP_ADDR_NOT_LOCKED); + sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED); #endif } } else { @@ -2421,8 +2428,7 @@ sctp_set_primary_ip_address(struct sctp_ifa *ifa) stcb->sctp_ep, stcb, stcb->asoc.primary_destination); #else - sctp_send_asconf(stcb, stcb->asoc.primary_destination, - SCTP_ADDR_NOT_LOCKED); + sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED); #endif } } @@ -2965,8 +2971,7 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m, stcb->sctp_ep, stcb, stcb->asoc.primary_destination); #else - sctp_send_asconf(stcb, stcb->asoc.primary_destination, - SCTP_ADDR_NOT_LOCKED); + sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED); #endif } } @@ -3540,5 +3545,5 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, } skip_rest: /* Now we must send the asconf into the queue */ - sctp_send_asconf(stcb, net, 0); + sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED); } |