diff options
| author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2006-09-22 04:33:58 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2006-09-24 16:49:26 -0400 |
| commit | 00e4d116a7ef94eb910be037912b0b2fc09f608b (patch) | |
| tree | 81e8a52c7529691b3c07605613da65cae80f41c9 | |
| parent | 1ab9dd0902df4f4ff56fbf672220549090ab28ba (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.txt | 8 | ||||
| -rw-r--r-- | include/linux/dccp.h | 6 | ||||
| -rw-r--r-- | net/dccp/ipv4.c | 3 | ||||
| -rw-r--r-- | net/dccp/proto.c | 11 |
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 @@ | |||
| 1 | DCCP protocol | 1 | DCCP protocol |
| 2 | ============ | 2 | ============ |
| 3 | 3 | ||
| 4 | Last updated: 10 November 2005 | ||
| 5 | 4 | ||
| 6 | Contents | 5 | Contents |
| 7 | ======== | 6 | ======== |
| @@ -42,8 +41,11 @@ Socket options | |||
| 42 | DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for | 41 | DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for |
| 43 | calculations. | 42 | calculations. |
| 44 | 43 | ||
| 45 | DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the | 44 | DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of |
| 46 | specification. If you don't set it you will get EPROTO. | 45 | service codes (RFC 4340, sec. 8.1.2); if this socket option is not set, |
| 46 | the socket will fall back to 0 (which means that no meaningful service code | ||
| 47 | is present). Connecting sockets set at most one service option; for | ||
| 48 | listening sockets, multiple service codes can be specified. | ||
| 47 | 49 | ||
| 48 | Notes | 50 | Notes |
| 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 | ||
| 408 | static inline int dccp_list_has_service(const struct dccp_service_list *sl, | 409 | static 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 | ||
| 487 | static inline int dccp_service_not_initialized(const struct sock *sk) | ||
| 488 | { | ||
| 489 | return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE; | ||
| 490 | } | ||
| 491 | |||
| 492 | static inline const char *dccp_role(const struct sock *sk) | 488 | static 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; |
