aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv4.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-16 19:58:40 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-16 19:58:40 -0400
commit67e6b629212fa9ffb7420e8a88a41806af637e28 (patch)
tree64f07616a23b657f3eb06e1daedf2450f6fbfc60 /net/dccp/ipv4.c
parent0c10c5d96865ce611d6a780888eff0ef4fab358b (diff)
[DCCP]: Introduce DCCP_SOCKOPT_SERVICE
As discussed in the dccp@vger mailing list: Now applications have to use setsockopt(DCCP_SOCKOPT_SERVICE, service[s]), prior to calling listen() and connect(). An array of unsigned ints can be passed meaning that the listening sock accepts connection requests for several services. With this we can ditch struct sockaddr_dccp and use only sockaddr_in (and sockaddr_in6 in the future). 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.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index e09907d8b7da..94a440b2685b 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -246,6 +246,9 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
246 246
247 dp->dccps_role = DCCP_ROLE_CLIENT; 247 dp->dccps_role = DCCP_ROLE_CLIENT;
248 248
249 if (dccp_service_not_initialized(sk))
250 return -EPROTO;
251
249 if (addr_len < sizeof(struct sockaddr_in)) 252 if (addr_len < sizeof(struct sockaddr_in))
250 return -EINVAL; 253 return -EINVAL;
251 254
@@ -661,6 +664,16 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
661 dccp_hdr(skb)->dccph_sport); 664 dccp_hdr(skb)->dccph_sport);
662} 665}
663 666
667static inline int dccp_bad_service_code(const struct sock *sk,
668 const __u32 service)
669{
670 const struct dccp_sock *dp = dccp_sk(sk);
671
672 if (dp->dccps_service == service)
673 return 0;
674 return !dccp_list_has_service(dp->dccps_service_list, service);
675}
676
664int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 677int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
665{ 678{
666 struct inet_request_sock *ireq; 679 struct inet_request_sock *ireq;
@@ -669,6 +682,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
669 struct dccp_request_sock *dreq; 682 struct dccp_request_sock *dreq;
670 const __u32 saddr = skb->nh.iph->saddr; 683 const __u32 saddr = skb->nh.iph->saddr;
671 const __u32 daddr = skb->nh.iph->daddr; 684 const __u32 daddr = skb->nh.iph->daddr;
685 const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
672 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 686 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
673 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; 687 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
674 struct dst_entry *dst = NULL; 688 struct dst_entry *dst = NULL;
@@ -680,6 +694,10 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
680 goto drop; 694 goto drop;
681 } 695 }
682 696
697 if (dccp_bad_service_code(sk, service)) {
698 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
699 goto drop;
700 }
683 /* 701 /*
684 * TW buckets are converted to open requests without 702 * TW buckets are converted to open requests without
685 * limitations, they conserve resources and peer is 703 * limitations, they conserve resources and peer is
@@ -722,9 +740,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
722 * dccp_create_openreq_child. 740 * dccp_create_openreq_child.
723 */ 741 */
724 dreq = dccp_rsk(req); 742 dreq = dccp_rsk(req);
725 dreq->dreq_isr = dcb->dccpd_seq; 743 dreq->dreq_isr = dcb->dccpd_seq;
726 dreq->dreq_iss = dccp_v4_init_sequence(sk, skb); 744 dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
727 dreq->dreq_service = dccp_hdr_request(skb)->dccph_req_service; 745 dreq->dreq_service = service;
728 746
729 if (dccp_v4_send_response(sk, req, dst)) 747 if (dccp_v4_send_response(sk, req, dst))
730 goto drop_and_free; 748 goto drop_and_free;
@@ -1284,6 +1302,7 @@ static int dccp_v4_init_sock(struct sock *sk)
1284 sk->sk_write_space = dccp_write_space; 1302 sk->sk_write_space = dccp_write_space;
1285 dp->dccps_mss_cache = 536; 1303 dp->dccps_mss_cache = 536;
1286 dp->dccps_role = DCCP_ROLE_UNDEFINED; 1304 dp->dccps_role = DCCP_ROLE_UNDEFINED;
1305 dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
1287 1306
1288 return 0; 1307 return 0;
1289} 1308}
@@ -1305,6 +1324,11 @@ static int dccp_v4_destroy_sock(struct sock *sk)
1305 if (inet_csk(sk)->icsk_bind_hash != NULL) 1324 if (inet_csk(sk)->icsk_bind_hash != NULL)
1306 inet_put_port(&dccp_hashinfo, sk); 1325 inet_put_port(&dccp_hashinfo, sk);
1307 1326
1327 if (dp->dccps_service_list != NULL) {
1328 kfree(dp->dccps_service_list);
1329 dp->dccps_service_list = NULL;
1330 }
1331
1308 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk); 1332 ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
1309 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk); 1333 ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
1310 dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts); 1334 dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts);