| 1659 | } |
| 1660 | |
| 1661 | void |
| 1662 | sctp_handle_asconf_ack(struct mbuf *m, int offset, |
| 1663 | struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb, |
| 1664 | struct sctp_nets *net, int *abort_no_unlock) |
| 1665 | { |
| 1666 | struct sctp_association *asoc; |
| 1667 | uint32_t serial_num; |
| 1668 | uint16_t ack_length; |
| 1669 | struct sctp_asconf_paramhdr *aph; |
| 1670 | struct sctp_asconf_addr *aa, *aa_next; |
| 1671 | uint32_t last_error_id = 0; /* last error correlation id */ |
| 1672 | uint32_t id; |
| 1673 | struct sctp_asconf_addr *ap; |
| 1674 | |
| 1675 | /* asconf param buffer */ |
| 1676 | uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE]; |
| 1677 | |
| 1678 | /* verify minimum length */ |
| 1679 | if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) { |
| 1680 | SCTPDBG(SCTP_DEBUG_ASCONF1, |
| 1681 | "handle_asconf_ack: chunk too small = %xh\n", |
| 1682 | ntohs(cp->ch.chunk_length)); |
| 1683 | return; |
| 1684 | } |
| 1685 | asoc = &stcb->asoc; |
| 1686 | serial_num = ntohl(cp->serial_number); |
| 1687 | |
| 1688 | /* |
| 1689 | * NOTE: we may want to handle this differently- currently, we will |
| 1690 | * abort when we get an ack for the expected serial number + 1 (eg. |
| 1691 | * we didn't send it), process an ack normally if it is the expected |
| 1692 | * serial number, and re-send the previous ack for *ALL* other |
| 1693 | * serial numbers |
| 1694 | */ |
| 1695 | |
| 1696 | /* |
| 1697 | * if the serial number is the next expected, but I didn't send it, |
| 1698 | * abort the asoc, since someone probably just hijacked us... |
| 1699 | */ |
| 1700 | if (serial_num == (asoc->asconf_seq_out + 1)) { |
| 1701 | struct mbuf *op_err; |
| 1702 | char msg[SCTP_DIAG_INFO_LEN]; |
| 1703 | |
| 1704 | SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n"); |
| 1705 | SCTP_SNPRINTF(msg, sizeof(msg), "Never sent serial number %8.8x", serial_num); |
| 1706 | op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg); |
| 1707 | sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); |
| 1708 | *abort_no_unlock = 1; |
| 1709 | return; |
| 1710 | } |
| 1711 | if (serial_num != asoc->asconf_seq_out_acked + 1) { |
| 1712 | /* got a duplicate/unexpected ASCONF-ACK */ |
| 1713 | SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n", |
| 1714 | serial_num, asoc->asconf_seq_out_acked + 1); |
| 1715 | return; |
| 1716 | } |
| 1717 | |
| 1718 | if (serial_num == asoc->asconf_seq_out - 1) { |
no test coverage detected