DCCP protocol
 ============
 
-Last updated: 10 November 2005
 
 Contents
 ========
 DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
 calculations.
 
-DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
-specification. If you don't set it you will get EPROTO.
+DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
+service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
+the socket will fall back to 0 (which means that no meaningful service code
+is present). Connecting sockets set at most one service option; for
+listening sockets, multiple service codes can be specified.
 
 Notes
 =====
 
 };
 
 #define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
+#define DCCP_SERVICE_CODE_IS_ABSENT             0
 
 static inline int dccp_list_has_service(const struct dccp_service_list *sl,
                                        const __be32 service)
        return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
 }
 
-static inline int dccp_service_not_initialized(const struct sock *sk)
-{
-       return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE;
-}
-
 static inline const char *dccp_role(const struct sock *sk)
 {
        switch (dccp_sk(sk)->dccps_role) {
 
 
        dp->dccps_role = DCCP_ROLE_CLIENT;
 
-       if (dccp_service_not_initialized(sk))
-               return -EPROTO;
-
        if (addr_len < sizeof(struct sockaddr_in))
                return -EINVAL;
 
 
        icsk->icsk_sync_mss     = dccp_sync_mss;
        dp->dccps_mss_cache     = 536;
        dp->dccps_role          = DCCP_ROLE_UNDEFINED;
-       dp->dccps_service       = DCCP_SERVICE_INVALID_VALUE;
+       dp->dccps_service       = DCCP_SERVICE_CODE_IS_ABSENT;
        dp->dccps_l_ack_ratio   = dp->dccps_r_ack_ratio = 1;
 
        return 0;
        struct dccp_sock *dp = dccp_sk(sk);
 
        dp->dccps_role = DCCP_ROLE_LISTEN;
-       /*
-        * Apps need to use setsockopt(DCCP_SOCKOPT_SERVICE)
-        * before calling listen()
-        */
-       if (dccp_service_not_initialized(sk))
-               return -EPROTO;
        return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE);
 }
 
        int err = -ENOENT, slen = 0, total_len = sizeof(u32);
 
        lock_sock(sk);
-       if (dccp_service_not_initialized(sk))
-               goto out;
-
        if ((sl = dp->dccps_service_list) != NULL) {
                slen = sl->dccpsl_nr * sizeof(u32);
                total_len += slen;