summaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv4.c
diff options
context:
space:
mode:
authorAndrea Bittau <a.bittau@cs.ucl.ac.uk>2006-03-20 17:43:56 -0800
committerDavid S. Miller <davem@davemloft.net>2006-03-20 17:43:56 -0800
commitafe00251dd9b53d51de91ff0099961f42bbf3754 (patch)
treea56aa987140662cf3e6e65be402b8591298c5ced /net/dccp/ipv4.c
parent2a91aa3967398fb94eccc8da67c82bce9f67afdf (diff)
downloadlinux-afe00251dd9b53d51de91ff0099961f42bbf3754.tar.gz
linux-afe00251dd9b53d51de91ff0099961f42bbf3754.tar.bz2
linux-afe00251dd9b53d51de91ff0099961f42bbf3754.zip
[DCCP]: Initial feature negotiation implementation
Still needs more work, but boots and doesn't crashes, even does some negotiation! 18:38:52.174934 127.0.0.1.43458 > 127.0.0.1.5001: request <change_l ack_ratio 2, change_r ccid 2, change_l ccid 2> 18:38:52.218526 127.0.0.1.5001 > 127.0.0.1.43458: response <nop, nop, change_l ack_ratio 2, confirm_r ccid 2 2, confirm_l ccid 2 2, confirm_r ack_ratio 2> 18:38:52.185398 127.0.0.1.43458 > 127.0.0.1.5001: <nop, confirm_r ack_ratio 2, ack_vector0 0x00, elapsed_time 212> :-) Signed-off-by: Andrea Bittau <a.bittau@cs.ucl.ac.uk> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r--net/dccp/ipv4.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 38321ad81875..fcfb486f90c2 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -28,6 +28,7 @@
#include "ackvec.h"
#include "ccid.h"
#include "dccp.h"
+#include "feat.h"
struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
.lhash_lock = RW_LOCK_UNLOCKED,
@@ -535,7 +536,8 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
if (req == NULL)
goto drop;
- /* FIXME: process options */
+ if (dccp_parse_options(sk, skb))
+ goto drop;
dccp_openreq_init(req, &dp, skb);
@@ -1049,6 +1051,8 @@ int dccp_v4_init_sock(struct sock *sk)
* setsockopt(CCIDs-I-want/accept). -acme
*/
if (likely(!dccp_ctl_socket_init)) {
+ int rc;
+
if (dp->dccps_options.dccpo_send_ack_vector) {
dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
if (dp->dccps_hc_rx_ackvec == NULL)
@@ -1069,8 +1073,16 @@ int dccp_v4_init_sock(struct sock *sk)
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
return -ENOMEM;
}
- } else
+
+ rc = dccp_feat_init(sk);
+ if (rc)
+ return rc;
+ } else {
+ /* control socket doesn't need feat nego */
+ INIT_LIST_HEAD(&dp->dccps_options.dccpo_pending);
+ INIT_LIST_HEAD(&dp->dccps_options.dccpo_conf);
dccp_ctl_socket_init = 0;
+ }
dccp_init_xmit_timers(sk);
icsk->icsk_rto = DCCP_TIMEOUT_INIT;
@@ -1118,6 +1130,9 @@ int dccp_v4_destroy_sock(struct sock *sk)
ccid_exit(dp->dccps_hc_tx_ccid, sk);
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
+ /* clean up feature negotiation state */
+ dccp_feat_clean(sk);
+
return 0;
}