aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2006-09-22 04:33:58 -0400
committerArnaldo Carvalho de Melo <acme@mandriva.com>2006-09-24 16:49:26 -0400
commit00e4d116a7ef94eb910be037912b0b2fc09f608b (patch)
tree81e8a52c7529691b3c07605613da65cae80f41c9
parent1ab9dd0902df4f4ff56fbf672220549090ab28ba (diff)
[DCCP]: Allow default/fallback service code.
This has been discussed on dccp@vger and removes the necessity for applications to supply service codes in each and every case. If an application does not want to provide a service code, that's fine, it will be given 0. Otherwise, service codes can be set via socket options as before. This patch has been tested using various client/server configurations (including listening on multiple service codes). Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
-rw-r--r--Documentation/networking/dccp.txt8
-rw-r--r--include/linux/dccp.h6
-rw-r--r--net/dccp/ipv4.c3
-rw-r--r--net/dccp/proto.c11
4 files changed, 7 insertions, 21 deletions
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
index c45daabd3bfe..74563b38ffd9 100644
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -1,7 +1,6 @@
1DCCP protocol 1DCCP protocol
2============ 2============
3 3
4Last updated: 10 November 2005
5 4
6Contents 5Contents
7======== 6========
@@ -42,8 +41,11 @@ Socket options
42DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for 41DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
43calculations. 42calculations.
44 43
45DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the 44DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
46specification. If you don't set it you will get EPROTO. 45service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
46the socket will fall back to 0 (which means that no meaningful service code
47is present). Connecting sockets set at most one service option; for
48listening sockets, multiple service codes can be specified.
47 49
48Notes 50Notes
49===== 51=====
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 2d7671c92c0b..29f9291e45c0 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -404,6 +404,7 @@ struct dccp_service_list {
404}; 404};
405 405
406#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1) 406#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
407#define DCCP_SERVICE_CODE_IS_ABSENT 0
407 408
408static inline int dccp_list_has_service(const struct dccp_service_list *sl, 409static inline int dccp_list_has_service(const struct dccp_service_list *sl,
409 const __be32 service) 410 const __be32 service)
@@ -484,11 +485,6 @@ static inline struct dccp_minisock *dccp_msk(const struct sock *sk)
484 return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock; 485 return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
485} 486}
486 487
487static inline int dccp_service_not_initialized(const struct sock *sk)
488{
489 return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE;
490}
491
492static inline const char *dccp_role(const struct sock *sk) 488static inline const char *dccp_role(const struct sock *sk)
493{ 489{
494 switch (dccp_sk(sk)->dccps_role) { 490 switch (dccp_sk(sk)->dccps_role) {
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 9a1a76a7dc41..66be29b6f508 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -56,9 +56,6 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
56 56
57 dp->dccps_role = DCCP_ROLE_CLIENT; 57 dp->dccps_role = DCCP_ROLE_CLIENT;
58 58
59 if (dccp_service_not_initialized(sk))
60 return -EPROTO;
61
62 if (addr_len < sizeof(struct sockaddr_in)) 59 if (addr_len < sizeof(struct sockaddr_in))
63 return -EINVAL; 60 return -EINVAL;
64 61
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 962df0ea31aa..72cbdcfc2c65 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -217,7 +217,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
217 icsk->icsk_sync_mss = dccp_sync_mss; 217 icsk->icsk_sync_mss = dccp_sync_mss;
218 dp->dccps_mss_cache = 536; 218 dp->dccps_mss_cache = 536;
219 dp->dccps_role = DCCP_ROLE_UNDEFINED; 219 dp->dccps_role = DCCP_ROLE_UNDEFINED;
220 dp->dccps_service = DCCP_SERVICE_INVALID_VALUE; 220 dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT;
221 dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1; 221 dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
222 222
223 return 0; 223 return 0;
@@ -267,12 +267,6 @@ static inline int dccp_listen_start(struct sock *sk)
267 struct dccp_sock *dp = dccp_sk(sk); 267 struct dccp_sock *dp = dccp_sk(sk);
268 268
269 dp->dccps_role = DCCP_ROLE_LISTEN; 269 dp->dccps_role = DCCP_ROLE_LISTEN;
270 /*
271 * Apps need to use setsockopt(DCCP_SOCKOPT_SERVICE)
272 * before calling listen()
273 */
274 if (dccp_service_not_initialized(sk))
275 return -EPROTO;
276 return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE); 270 return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE);
277} 271}
278 272
@@ -540,9 +534,6 @@ static int dccp_getsockopt_service(struct sock *sk, int len,
540 int err = -ENOENT, slen = 0, total_len = sizeof(u32); 534 int err = -ENOENT, slen = 0, total_len = sizeof(u32);
541 535
542 lock_sock(sk); 536 lock_sock(sk);
543 if (dccp_service_not_initialized(sk))
544 goto out;
545
546 if ((sl = dp->dccps_service_list) != NULL) { 537 if ((sl = dp->dccps_service_list) != NULL) {
547 slen = sl->dccpsl_nr * sizeof(u32); 538 slen = sl->dccpsl_nr * sizeof(u32);
548 total_len += slen; 539 total_len += slen;