9
9
#include <arpa/inet.h>
10
10
#include <errno.h>
11
11
#include <error.h>
12
+ #include <linux/dccp.h>
12
13
#include <linux/in.h>
13
14
#include <linux/unistd.h>
14
15
#include <stdbool.h>
@@ -75,7 +76,16 @@ static void build_rcv_fd(int family, int proto, int *rcv_fds, int count,
75
76
error (1 , errno , "failed to bind receive socket" );
76
77
77
78
if (proto == SOCK_STREAM && listen (rcv_fds [i ], 10 ))
78
- error (1 , errno , "failed to listen on receive port" );
79
+ error (1 , errno , "tcp: failed to listen on receive port" );
80
+ else if (proto == SOCK_DCCP ) {
81
+ if (setsockopt (rcv_fds [i ], SOL_DCCP ,
82
+ DCCP_SOCKOPT_SERVICE ,
83
+ & (int ) {htonl (42 )}, sizeof (int )))
84
+ error (1 , errno , "failed to setsockopt" );
85
+
86
+ if (listen (rcv_fds [i ], 10 ))
87
+ error (1 , errno , "dccp: failed to listen on receive port" );
88
+ }
79
89
}
80
90
}
81
91
@@ -124,6 +134,11 @@ static int connect_and_send(int family, int proto)
124
134
if (fd < 0 )
125
135
error (1 , errno , "failed to create send socket" );
126
136
137
+ if (proto == SOCK_DCCP &&
138
+ setsockopt (fd , SOL_DCCP , DCCP_SOCKOPT_SERVICE ,
139
+ & (int ){htonl (42 )}, sizeof (int )))
140
+ error (1 , errno , "failed to setsockopt" );
141
+
127
142
if (bind (fd , saddr , sz ))
128
143
error (1 , errno , "failed to bind send socket" );
129
144
@@ -146,7 +161,7 @@ static int receive_once(int epfd, int proto)
146
161
if (i < 0 )
147
162
error (1 , errno , "epoll_wait failed" );
148
163
149
- if (proto == SOCK_STREAM ) {
164
+ if (proto == SOCK_STREAM || proto == SOCK_DCCP ) {
150
165
fd = accept (ev .data .fd , NULL , NULL );
151
166
if (fd < 0 )
152
167
error (1 , errno , "failed to accept" );
@@ -259,6 +274,36 @@ int main(void)
259
274
for (i = 0 ; i < 9 ; ++ i )
260
275
close (rcv_fds [i ]);
261
276
277
+ fprintf (stderr , "---- DCCP IPv4 ----\n" );
278
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds , 2 , NULL );
279
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 2 , 2 , NULL );
280
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds + 4 , 1 , IP4_ADDR );
281
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds + 5 , 2 , NULL );
282
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 7 , 2 , NULL );
283
+ test (rcv_fds , 9 , AF_INET , SOCK_DCCP , rcv_fds [4 ]);
284
+ for (i = 0 ; i < 9 ; ++ i )
285
+ close (rcv_fds [i ]);
286
+
287
+ fprintf (stderr , "---- DCCP IPv6 ----\n" );
288
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds , 2 , NULL );
289
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 2 , 2 , NULL );
290
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 4 , 1 , IP6_ADDR );
291
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds + 5 , 2 , NULL );
292
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 7 , 2 , NULL );
293
+ test (rcv_fds , 9 , AF_INET6 , SOCK_DCCP , rcv_fds [4 ]);
294
+ for (i = 0 ; i < 9 ; ++ i )
295
+ close (rcv_fds [i ]);
296
+
297
+ fprintf (stderr , "---- DCCP IPv4 mapped to IPv6 ----\n" );
298
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds , 2 , NULL );
299
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 2 , 2 , NULL );
300
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 4 , 1 , IP4_MAPPED6 );
301
+ build_rcv_fd (AF_INET , SOCK_DCCP , rcv_fds + 5 , 2 , NULL );
302
+ build_rcv_fd (AF_INET6 , SOCK_DCCP , rcv_fds + 7 , 2 , NULL );
303
+ test (rcv_fds , 9 , AF_INET , SOCK_DCCP , rcv_fds [4 ]);
304
+ for (i = 0 ; i < 9 ; ++ i )
305
+ close (rcv_fds [i ]);
306
+
262
307
fprintf (stderr , "SUCCESS\n" );
263
308
return 0 ;
264
309
}
0 commit comments