X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Fnet%2Fsctp%2Fstructs.h;h=23f08fe1d50ae29980f7b192fbcf6943ea1c73d6;hb=faee47cdbfe8d74a1573c2f81ea6dbb08d735be6;hp=5596f5d97ed2a73e108e946320be3e1117c4d39b;hpb=b68dbcab1dc70938fa5516d0ee82c0bf94e9a768;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 5596f5d..23f08fe 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1,18 +1,18 @@ -/* SCTP kernel reference Implementation +/* SCTP kernel implementation * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001 Intel Corp. * - * This file is part of the SCTP kernel reference Implementation + * This file is part of the SCTP kernel implementation * - * The SCTP reference implementation is free software; + * This SCTP implementation is free software; * you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * - * The SCTP reference implementation is distributed in the hope that it + * This SCTP implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -64,6 +64,7 @@ #include /* We need sk_buff_head. */ #include /* We need tq_struct. */ #include /* We need sctp* header structs. */ +#include /* We need auth specific structs */ /* A convenience structure for handling sockaddr structures. * We should wean ourselves off this. @@ -99,20 +100,19 @@ struct crypto_hash; struct sctp_bind_bucket { unsigned short port; unsigned short fastreuse; - struct sctp_bind_bucket *next; - struct sctp_bind_bucket **pprev; + struct hlist_node node; struct hlist_head owner; }; struct sctp_bind_hashbucket { spinlock_t lock; - struct sctp_bind_bucket *chain; + struct hlist_head chain; }; /* Used for hashing all associations. */ struct sctp_hashbucket { rwlock_t lock; - struct sctp_ep_common *chain; + struct hlist_head chain; } __attribute__((__aligned__(8))); @@ -196,24 +196,32 @@ extern struct sctp_globals { /* This is the sctp port control hash. */ int port_hashsize; - int port_rover; - spinlock_t port_alloc_lock; /* Protects port_rover. */ struct sctp_bind_hashbucket *port_hashtable; /* This is the global local address list. - * We actively maintain this complete list of interfaces on - * the system by catching routing events. + * We actively maintain this complete list of addresses on + * the system by catching address add/delete events. * * It is a list of sctp_sockaddr_entry. */ struct list_head local_addr_list; - spinlock_t local_addr_lock; + + /* Lock that protects the local_addr_list writers */ + spinlock_t addr_list_lock; /* Flag to indicate if addip is enabled. */ int addip_enable; + int addip_noauth_enable; /* Flag to indicate if PR-SCTP is enabled. */ int prsctp_enable; + + /* Flag to idicate if SCTP-AUTH is enabled */ + int auth_enable; + + /* Flag to indicate whether computing and verifying checksum + * is disabled. */ + int checksum_disable; } sctp_globals; #define sctp_rto_initial (sctp_globals.rto_initial) @@ -243,9 +251,12 @@ extern struct sctp_globals { #define sctp_port_alloc_lock (sctp_globals.port_alloc_lock) #define sctp_port_hashtable (sctp_globals.port_hashtable) #define sctp_local_addr_list (sctp_globals.local_addr_list) -#define sctp_local_addr_lock (sctp_globals.local_addr_lock) +#define sctp_local_addr_lock (sctp_globals.addr_list_lock) #define sctp_addip_enable (sctp_globals.addip_enable) +#define sctp_addip_noauth (sctp_globals.addip_noauth_enable) #define sctp_prsctp_enable (sctp_globals.prsctp_enable) +#define sctp_auth_enable (sctp_globals.auth_enable) +#define sctp_checksum_disable (sctp_globals.checksum_disable) /* SCTP Socket type: UDP or TCP style. */ typedef enum { @@ -277,6 +288,8 @@ struct sctp_sock { __u16 default_flags; __u32 default_context; __u32 default_timetolive; + __u32 default_rcv_context; + int max_burst; /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to * the destination address every heartbeat interval. This value @@ -292,8 +305,9 @@ struct sctp_sock { /* The default SACK delay timeout for new associations. */ __u32 sackdelay; + __u32 sackfreq; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; struct sctp_initmsg initmsg; @@ -305,10 +319,12 @@ struct sctp_sock { __u32 autoclose; __u8 nodelay; __u8 disable_fragments; - __u8 pd_mode; __u8 v4mapped; - __u32 adaption_ind; + __u8 frag_interleave; + __u32 adaptation_ind; + __u32 pd_point; + atomic_t pd_mode; /* Receive to here while partial delivery is in effect. */ struct sk_buff_head pd_lobby; }; @@ -389,8 +405,11 @@ struct sctp_cookie { /* Padding for future use */ __u8 padding; - __u32 adaption_ind; + __u32 adaptation_ind; + __u8 auth_random[sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH]; + __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS + 2]; + __u8 auth_chunks[sizeof(sctp_paramhdr_t) + SCTP_AUTH_MAX_CHUNKS]; /* This is a shim for my peer's INIT packet, followed by * a copy of the raw address list of the association. @@ -415,6 +434,7 @@ struct sctp_signed_cookie { * internally. */ union sctp_addr_param { + struct sctp_paramhdr p; struct sctp_ipv4addr_param v4; struct sctp_ipv6addr_param v6; }; @@ -432,7 +452,12 @@ union sctp_params { struct sctp_ipv4addr_param *v4; struct sctp_ipv6addr_param *v6; union sctp_addr_param *addr; - struct sctp_adaption_ind_param *aind; + struct sctp_adaptation_ind_param *aind; + struct sctp_supported_ext_param *ext; + struct sctp_random_param *random; + struct sctp_chunks_param *chunks; + struct sctp_hmac_algo_param *hmac_algo; + struct sctp_addip_param *addip; }; /* RFC 2960. Section 3.3.5 Heartbeat. @@ -504,8 +529,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, */ struct sctp_af { int (*sctp_xmit) (struct sk_buff *skb, - struct sctp_transport *, - int ipfragok); + struct sctp_transport *); int (*setsockopt) (struct sock *sk, int level, int optname, @@ -529,7 +553,8 @@ struct sctp_af { struct dst_entry *(*get_dst) (struct sctp_association *asoc, union sctp_addr *daddr, union sctp_addr *saddr); - void (*get_saddr) (struct sctp_association *asoc, + void (*get_saddr) (struct sctp_sock *sk, + struct sctp_association *asoc, struct dst_entry *dst, union sctp_addr *daddr, union sctp_addr *saddr); @@ -537,7 +562,7 @@ struct sctp_af { struct net_device *); void (*dst_saddr) (union sctp_addr *saddr, struct dst_entry *dst, - unsigned short port); + __be16 port); int (*cmp_addr) (const union sctp_addr *addr1, const union sctp_addr *addr2); void (*addr_copy) (union sctp_addr *dst, @@ -553,14 +578,14 @@ struct sctp_af { struct sock *sk); void (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, - __u16 port, int iif); + __be16 port, int iif); int (*to_addr_param) (const union sctp_addr *, union sctp_addr_param *); int (*addr_valid) (union sctp_addr *, struct sctp_sock *, const struct sk_buff *); sctp_scope_t (*scope) (union sctp_addr *); - void (*inaddr_any) (union sctp_addr *, unsigned short); + void (*inaddr_any) (union sctp_addr *, __be16); int (*is_any) (const union sctp_addr *); int (*available) (union sctp_addr *, struct sctp_sock *); @@ -568,6 +593,7 @@ struct sctp_af { int (*is_ce) (const struct sk_buff *sk); void (*seq_dump_addr)(struct seq_file *seq, union sctp_addr *addr); + void (*ecn_capable)(struct sock *sk); __u16 net_header_len; int sockaddr_len; sa_family_t sa_family; @@ -587,7 +613,7 @@ struct sctp_pf { struct sctp_sock *); int (*bind_verify) (struct sctp_sock *, union sctp_addr *); int (*send_verify) (struct sctp_sock *, union sctp_addr *); - int (*supported_addrs)(const struct sctp_sock *, __u16 *); + int (*supported_addrs)(const struct sctp_sock *, __be16 *); struct sock *(*create_accept_sk) (struct sock *sk, struct sctp_association *asoc); void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); @@ -618,8 +644,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, struct sctp_sndrcvinfo *, struct msghdr *, int len); void sctp_datamsg_put(struct sctp_datamsg *); -void sctp_datamsg_free(struct sctp_datamsg *); -void sctp_datamsg_track(struct sctp_chunk *); void sctp_chunk_fail(struct sctp_chunk *, int error); int sctp_chunk_abandoned(struct sctp_chunk *); @@ -671,6 +695,7 @@ struct sctp_chunk { struct sctp_errhdr *err_hdr; struct sctp_addiphdr *addip_hdr; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_authhdr *auth_hdr; } subh; __u8 *chunk_end; @@ -704,18 +729,30 @@ struct sctp_chunk { */ struct sctp_transport *transport; - __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */ - __u8 resent; /* Has this chunk ever been retransmitted. */ - __u8 has_tsn; /* Does this chunk have a TSN yet? */ - __u8 has_ssn; /* Does this chunk have a SSN yet? */ - __u8 singleton; /* Was this the only chunk in the packet? */ - __u8 end_of_packet; /* Was this the last chunk in the packet? */ - __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ - __u8 pdiscard; /* Discard the whole packet now? */ - __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ - __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ - __u8 tsn_missing_report; /* Data chunk missing counter. */ - __u8 data_accepted; /* At least 1 chunk in this packet accepted */ + /* SCTP-AUTH: For the special case inbound processing of COOKIE-ECHO + * we need save a pointer to the AUTH chunk, since the SCTP-AUTH + * spec violates the principle premis that all chunks are processed + * in order. + */ + struct sk_buff *auth_chunk; + +#define SCTP_CAN_FRTX 0x0 +#define SCTP_NEED_FRTX 0x1 +#define SCTP_DONT_FRTX 0x2 + __u16 rtt_in_progress:1, /* This chunk used for RTT calc? */ + resent:1, /* Has this chunk ever been resent. */ + has_tsn:1, /* Does this chunk have a TSN yet? */ + has_ssn:1, /* Does this chunk have a SSN yet? */ + singleton:1, /* Only chunk in the packet? */ + end_of_packet:1, /* Last chunk in the packet? */ + ecn_ce_done:1, /* Have we processed the ECN CE bit? */ + pdiscard:1, /* Discard the whole packet now? */ + tsn_gap_acked:1, /* Is this chunk acked by a GAP ACK? */ + data_accepted:1, /* At least 1 chunk accepted */ + auth:1, /* IN: was auth'ed | OUT: needs auth */ + has_asconf:1, /* IN: have seen an asconf before */ + tsn_missing_report:2, /* Data chunk missing counter. */ + fast_retransmit:2; /* Is this chunk fast retransmitted? */ }; void sctp_chunk_hold(struct sctp_chunk *); @@ -731,11 +768,19 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, union sctp_addr *); const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); +enum { + SCTP_ADDR_NEW, /* new address added to assoc/ep */ + SCTP_ADDR_SRC, /* address can be used as source */ + SCTP_ADDR_DEL, /* address about to be deleted */ +}; + /* This is a structure for holding either an IPv6 or an IPv4 address. */ struct sctp_sockaddr_entry { struct list_head list; + struct rcu_head rcu; union sctp_addr a; - __u8 use_as_src; + __u8 state; + __u8 valid; }; typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); @@ -763,16 +808,25 @@ struct sctp_packet { */ struct sctp_transport *transport; + /* pointer to the auth chunk for this packet */ + struct sctp_chunk *auth; + /* This packet contains a COOKIE-ECHO chunk. */ - char has_cookie_echo; + __u8 has_cookie_echo; + + /* This packet contains a SACK chunk. */ + __u8 has_sack; - /* This packet containsa SACK chunk. */ - char has_sack; + /* This packet contains an AUTH chunk */ + __u8 has_auth; + + /* This packet contains at least 1 DATA chunk */ + __u8 has_data; /* SCTP cannot fragment this packet. So let ip fragment it. */ - char ipfragok; + __u8 ipfragok; - int malloced; + __u8 malloced; }; struct sctp_packet *sctp_packet_init(struct sctp_packet *, @@ -780,7 +834,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *, __u16 sport, __u16 dport); struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int); sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *, - struct sctp_chunk *); + struct sctp_chunk *, int); sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *, struct sctp_chunk *); int sctp_packet_transmit(struct sctp_packet *); @@ -836,10 +890,11 @@ struct sctp_transport { * address list derived from the INIT or INIT ACK chunk, a * number of data elements needs to be maintained including: */ - __u32 rtt; /* This is the most recent RTT. */ - /* RTO : The current retransmission timeout value. */ unsigned long rto; + unsigned long last_rto; + + __u32 rtt; /* This is the most recent RTT. */ /* RTTVAR : The current RTT variation. */ __u32 rttvar; @@ -855,8 +910,13 @@ struct sctp_transport { * should be set. Every time the RTT * calculation completes (i.e. the DATA chunk * is SACK'd) clear this flag. + * hb_sent : a flag that signals that we have a pending heartbeat. */ - int rto_pending; + __u8 rto_pending; + __u8 hb_sent; + + /* Flag to track the current fast recovery state */ + __u8 fast_recovery; /* * These are the congestion stats. @@ -875,6 +935,9 @@ struct sctp_transport { /* Data that has been sent, but not acknowledged. */ __u32 flight_size; + /* TSN marking the fast recovery exit point */ + __u32 fast_recovery_exit; + /* Destination */ struct dst_entry *dst; /* Source address. */ @@ -893,6 +956,7 @@ struct sctp_transport { /* SACK delay timeout */ unsigned long sackdelay; + __u32 sackfreq; /* When was the last time (in jiffies) that we heard from this * transport? We use this to pick new active and retran paths. @@ -910,10 +974,13 @@ struct sctp_transport { */ __u16 pathmaxrxt; + /* is the Path MTU update pending on this tranport */ + __u8 pmtu_pending; + /* PMTU : The current known path MTU. */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* The number of times INIT has been sent on this transport. */ @@ -996,13 +1063,15 @@ void sctp_transport_route(struct sctp_transport *, union sctp_addr *, struct sctp_sock *); void sctp_transport_pmtu(struct sctp_transport *); void sctp_transport_free(struct sctp_transport *); -void sctp_transport_reset_timers(struct sctp_transport *); +void sctp_transport_reset_timers(struct sctp_transport *, int); void sctp_transport_hold(struct sctp_transport *); void sctp_transport_put(struct sctp_transport *); void sctp_transport_update_rto(struct sctp_transport *, __u32); void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); unsigned long sctp_transport_timeout(struct sctp_transport *); +void sctp_transport_reset(struct sctp_transport *); +void sctp_transport_update_pmtu(struct sctp_transport *, u32); /* This is the structure we use to queue packets as they come into @@ -1030,7 +1099,8 @@ void sctp_inq_init(struct sctp_inq *); void sctp_inq_free(struct sctp_inq *); void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); -void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *); +struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *); +void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t); /* This is the structure we use to hold outbound chunks. You push * chunks in and they automatically pop out the other end as bundled @@ -1083,6 +1153,9 @@ struct sctp_outq { /* How many unackd bytes do we have in-flight? */ __u32 outstanding_bytes; + /* Are we doing fast-rtx on this queue */ + char fast_rtx; + /* Corked? */ char cork; @@ -1097,7 +1170,6 @@ void sctp_outq_init(struct sctp_association *, struct sctp_outq *); void sctp_outq_teardown(struct sctp_outq *); void sctp_outq_free(struct sctp_outq*); int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); -int sctp_outq_flush(struct sctp_outq *, int); int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_is_empty(const struct sctp_outq *); void sctp_outq_restart(struct sctp_outq *); @@ -1139,11 +1211,18 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, const struct sctp_bind_addr *src, sctp_scope_t scope, gfp_t gfp, int flags); +int sctp_bind_addr_dup(struct sctp_bind_addr *dest, + const struct sctp_bind_addr *src, + gfp_t gfp); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, - __u8 use_as_src, gfp_t gfp); + __u8 addr_state, gfp_t gfp); int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); +int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *, + struct sctp_sock *, struct sctp_sock *); +int sctp_bind_addr_state(const struct sctp_bind_addr *bp, + const union sctp_addr *addr); union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, const union sctp_addr *addrs, int addrcnt, @@ -1156,7 +1235,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len, sctp_scope_t sctp_scope(const union sctp_addr *); int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope); -int sctp_is_any(const union sctp_addr *addr); +int sctp_is_any(struct sock *sk, const union sctp_addr *addr); int sctp_addr_is_valid(const union sctp_addr *addr); @@ -1184,8 +1263,7 @@ typedef enum { struct sctp_ep_common { /* Fields to help us manage our entries in the hash tables. */ - struct sctp_ep_common *next; - struct sctp_ep_common **pprev; + struct hlist_node node; int hashent; /* Runtime type information. What kind of endpoint is this? */ @@ -1212,9 +1290,6 @@ struct sctp_ep_common { * bind_addr.address_list is our set of local IP addresses. */ struct sctp_bind_addr bind_addr; - - /* Protection during address list comparisons. */ - rwlock_t addr_lock; }; @@ -1277,6 +1352,21 @@ struct sctp_endpoint { /* rcvbuf acct. policy. */ __u32 rcvbuf_policy; + + /* SCTP AUTH: array of the HMACs that will be allocated + * we need this per association so that we don't serialize + */ + struct crypto_hash **auth_hmacs; + + /* SCTP-AUTH: hmacs for the endpoint encoded into parameter */ + struct sctp_hmac_algo_param *auth_hmacs_list; + + /* SCTP-AUTH: chunks to authenticate encoded into parameter */ + struct sctp_chunks_param *auth_chunk_list; + + /* SCTP-AUTH: endpoint shared keys */ + struct list_head endpoint_shared_keys; + __u16 active_key_id; }; /* Recover the outter endpoint structure. */ @@ -1314,6 +1404,13 @@ int sctp_process_init(struct sctp_association *, sctp_cid_t cid, __u32 sctp_generate_tag(const struct sctp_endpoint *); __u32 sctp_generate_tsn(const struct sctp_endpoint *); +struct sctp_inithdr_host { + __u32 init_tag; + __u32 a_rwnd; + __u16 num_outbound_streams; + __u16 num_inbound_streams; + __u32 initial_tsn; +}; /* RFC2960 * @@ -1455,7 +1552,6 @@ struct sctp_association { * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). */ struct sctp_tsnmap tsn_map; - __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)]; /* Ack State : This flag indicates if the next received * : packet is to be responded to with a @@ -1468,6 +1564,7 @@ struct sctp_association { * : SACK's are not delayed (see Section 6). */ __u8 sack_needed; /* Do we need to sack the peer? */ + __u32 sack_cnt; /* These are capabilities which our peer advertised. */ __u8 ecn_capable; /* Can peer do ECN? */ @@ -1476,15 +1573,16 @@ struct sctp_association { __u8 hostname_address;/* Peer understands DNS addresses? */ __u8 asconf_capable; /* Does peer support ADDIP? */ __u8 prsctp_capable; /* Can peer do PR-SCTP? */ + __u8 auth_capable; /* Is peer doing SCTP-AUTH? */ - __u32 adaption_ind; /* Adaption Code point. */ + __u32 adaptation_ind; /* Adaptation Code point. */ /* This mask is used to disable sending the ASCONF chunk * with specified parameter to peer. */ - __u16 addip_disabled_mask; + __be16 addip_disabled_mask; - struct sctp_inithdr i; + struct sctp_inithdr_host i; int cookie_len; void *cookie; @@ -1493,6 +1591,14 @@ struct sctp_association { * Initial TSN Value minus 1 */ __u32 addip_serial; + + /* SCTP-AUTH: We need to know pears random number, hmac list + * and authenticated chunk list. All that is part of the + * cookie and these are just pointers to those locations + */ + sctp_random_param_t *peer_random; + sctp_chunks_param_t *peer_chunks; + sctp_hmac_algo_param_t *peer_hmacs; } peer; /* State : A state variable indicating what state the @@ -1555,16 +1661,20 @@ struct sctp_association { */ __u16 pathmaxrxt; + /* Flag that path mtu update is pending */ + __u8 pmtu_pending; + /* Association : The smallest PMTU discovered for all of the * PMTU : peer's transport addresses. */ __u32 pathmtu; - /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ + /* Flags controlling Heartbeat, SACK delay, and Path MTU Discovery. */ __u32 param_flags; /* SACK delay timeout */ unsigned long sackdelay; + __u32 sackfreq; unsigned long timeouts[SCTP_NUM_TIMEOUT_TYPES]; @@ -1573,6 +1683,9 @@ struct sctp_association { /* Transport to which SHUTDOWN chunk was last sent. */ struct sctp_transport *shutdown_last_sent_to; + /* How many times have we resent a SHUTDOWN */ + int shutdown_retries; + /* Transport to which INIT chunk was last sent. */ struct sctp_transport *init_last_sent_to; @@ -1607,6 +1720,11 @@ struct sctp_association { */ __u16 unack_data; + /* The total number of data chunks that we've had to retransmit + * as the result of a T3 timer expiration + */ + __u32 rtx_data_chunks; + /* This is the association's receive buffer space. This value is used * to set a_rwnd field in an INIT or a SACK chunk. */ @@ -1652,6 +1770,9 @@ struct sctp_association { __u32 default_context; __u32 default_timetolive; + /* Default receive parameters */ + __u32 default_rcv_context; + /* This tracks outbound ssn for a given stream. */ struct sctp_ssnmap *ssnmap; @@ -1703,20 +1824,16 @@ struct sctp_association { */ struct sctp_chunk *addip_last_asconf; - /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. + /* ADDIP Section 5.2 Upon reception of an ASCONF Chunk. * - * IMPLEMENTATION NOTE: As an optimization a receiver may wish - * to save the last ASCONF-ACK for some predetermined period - * of time and instead of re-processing the ASCONF (with the - * same serial number) it may just re-transmit the - * ASCONF-ACK. It may wish to use the arrival of a new serial - * number to discard the previously saved ASCONF-ACK or any - * other means it may choose to expire the saved ASCONF-ACK. + * This is needed to implement itmes E1 - E4 of the updated + * spec. Here is the justification: * - * [This is our saved ASCONF-ACK. We invalidate it when a new - * ASCONF serial number arrives.] + * Since the peer may bundle multiple ASCONF chunks toward us, + * we now need the ability to cache multiple ACKs. The section + * describes in detail how they are cached and cleaned up. */ - struct sctp_chunk *addip_last_asconf_ack; + struct list_head asconf_ack_list; /* These ASCONF chunks are waiting to be sent. * @@ -1770,6 +1887,24 @@ struct sctp_association { */ __u32 addip_serial; + /* SCTP AUTH: list of the endpoint shared keys. These + * keys are provided out of band by the user applicaton + * and can't change during the lifetime of the association + */ + struct list_head endpoint_shared_keys; + + /* SCTP AUTH: + * The current generated assocaition shared key (secret) + */ + struct sctp_auth_bytes *asoc_shared_key; + + /* SCTP AUTH: hmac id of the first peer requested algorithm + * that we support. + */ + __u16 default_hmac_id; + + __u16 active_key_id; + /* Need to send an ECNE Chunk? */ char need_ecne; @@ -1839,11 +1974,19 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned); void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned); void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); +void sctp_assoc_del_nonprimary_peers(struct sctp_association *, + struct sctp_transport *); int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, gfp_t); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, struct sctp_cookie*, gfp_t gfp); +int sctp_assoc_set_id(struct sctp_association *, gfp_t); +void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc); +struct sctp_chunk *sctp_assoc_lookup_asconf_ack( + const struct sctp_association *asoc, + __be32 serial); + int sctp_cmp_addr_exact(const union sctp_addr *ss1, const union sctp_addr *ss2);