1 1.1 rjs /* $KAME: dccp_usrreq.c,v 1.67 2005/11/03 16:05:04 nishida Exp $ */ 2 1.27 rin /* $NetBSD: dccp_usrreq.c,v 1.27 2024/07/05 04:31:54 rin Exp $ */ 3 1.1 rjs 4 1.1 rjs /* 5 1.1 rjs * Copyright (c) 2003 Joacim Hggmark, Magnus Erixzon, Nils-Erik Mattsson 6 1.1 rjs * All rights reserved. 7 1.1 rjs * 8 1.1 rjs * Redistribution and use in source and binary forms, with or without 9 1.1 rjs * modification, are permitted provided that the following conditions 10 1.1 rjs * are met: 11 1.1 rjs * 12 1.1 rjs * 1. Redistributions of source code must retain the above copyright 13 1.1 rjs * notice, this list of conditions and the following disclaimer. 14 1.1 rjs * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 rjs * notice, this list of conditions and the following disclaimer in the 16 1.1 rjs * documentation and/or other materials provided with the distribution. 17 1.1 rjs * 3. The name of the author may not be used to endorse or promote products 18 1.1 rjs * derived from this software without specific prior written permission. 19 1.1 rjs * 20 1.1 rjs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 1.1 rjs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 1.1 rjs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 1.1 rjs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 1.1 rjs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 1.1 rjs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 1.1 rjs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 1.1 rjs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 1.1 rjs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 1.1 rjs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 1.1 rjs * 31 1.1 rjs * Id: dccp_usrreq.c,v 1.47 2003/07/31 11:23:08 joahag-9 Exp 32 1.1 rjs */ 33 1.1 rjs 34 1.1 rjs /* 35 1.1 rjs * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 36 1.1 rjs * The Regents of the University of California. All rights reserved. 37 1.1 rjs * 38 1.1 rjs * Redistribution and use in source and binary forms, with or without 39 1.1 rjs * modification, are permitted provided that the following conditions 40 1.1 rjs * are met: 41 1.1 rjs * 1. Redistributions of source code must retain the above copyright 42 1.1 rjs * notice, this list of conditions and the following disclaimer. 43 1.1 rjs * 2. Redistributions in binary form must reproduce the above copyright 44 1.1 rjs * notice, this list of conditions and the following disclaimer in the 45 1.1 rjs * documentation and/or other materials provided with the distribution. 46 1.1 rjs * 3. All advertising materials mentioning features or use of this software 47 1.1 rjs * must display the following acknowledgement: 48 1.1 rjs * This product includes software developed by the University of 49 1.1 rjs * California, Berkeley and its contributors. 50 1.1 rjs * 4. Neither the name of the University nor the names of its contributors 51 1.1 rjs * may be used to endorse or promote products derived from this software 52 1.1 rjs * without specific prior written permission. 53 1.1 rjs * 54 1.1 rjs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 1.1 rjs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 1.1 rjs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 1.1 rjs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 1.1 rjs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 1.1 rjs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 1.1 rjs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 1.1 rjs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 1.1 rjs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 1.1 rjs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 1.1 rjs * SUCH DAMAGE. 65 1.1 rjs * 66 1.1 rjs * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 67 1.1 rjs */ 68 1.1 rjs 69 1.1 rjs #include <sys/cdefs.h> 70 1.27 rin __KERNEL_RCSID(0, "$NetBSD: dccp_usrreq.c,v 1.27 2024/07/05 04:31:54 rin Exp $"); 71 1.1 rjs 72 1.7 pooka #ifdef _KERNEL_OPT 73 1.1 rjs #include "opt_inet.h" 74 1.1 rjs #include "opt_dccp.h" 75 1.7 pooka #endif 76 1.1 rjs 77 1.1 rjs #include <sys/param.h> 78 1.1 rjs #include <sys/systm.h> 79 1.1 rjs #include <sys/domain.h> 80 1.1 rjs #include <sys/kernel.h> 81 1.1 rjs #include <sys/pool.h> 82 1.1 rjs #include <sys/lock.h> 83 1.1 rjs #include <sys/malloc.h> 84 1.1 rjs #include <sys/mbuf.h> 85 1.1 rjs #include <sys/proc.h> 86 1.1 rjs #include <sys/protosw.h> 87 1.1 rjs #include <sys/signalvar.h> 88 1.1 rjs #include <sys/socket.h> 89 1.1 rjs #include <sys/socketvar.h> 90 1.1 rjs #include <sys/mutex.h> 91 1.1 rjs #include <sys/sysctl.h> 92 1.1 rjs #include <sys/syslog.h> 93 1.1 rjs #include <sys/queue.h> 94 1.1 rjs 95 1.1 rjs #include <net/if.h> 96 1.1 rjs 97 1.1 rjs #include <netinet/in.h> 98 1.1 rjs #include <netinet/in_systm.h> 99 1.1 rjs #include <netinet/ip.h> 100 1.1 rjs #include <netinet/in_pcb.h> 101 1.1 rjs #include <netinet/in_var.h> 102 1.1 rjs #ifdef INET6 103 1.1 rjs #include <netinet/ip6.h> 104 1.1 rjs #endif 105 1.1 rjs #include <netinet/ip_icmp.h> 106 1.1 rjs #include <netinet/icmp_var.h> 107 1.1 rjs #include <netinet/ip_var.h> 108 1.1 rjs #ifdef INET6 109 1.1 rjs #include <netinet6/in6_pcb.h> 110 1.1 rjs #include <netinet6/ip6_var.h> 111 1.1 rjs #include <netinet6/dccp6_var.h> 112 1.1 rjs #endif 113 1.1 rjs #include <netinet/dccp.h> 114 1.1 rjs #include <netinet/dccp_var.h> 115 1.1 rjs #include <netinet/dccp_cc_sw.h> 116 1.1 rjs 117 1.1 rjs #define DEFAULT_CCID 2 118 1.1 rjs 119 1.1 rjs #define INP_INFO_LOCK_INIT(x,y) 120 1.1 rjs #define INP_INFO_WLOCK(x) 121 1.1 rjs #define INP_INFO_WUNLOCK(x) 122 1.1 rjs #define INP_INFO_RLOCK(x) 123 1.1 rjs #define INP_INFO_RUNLOCK(x) 124 1.1 rjs #define INP_LOCK(x) 125 1.1 rjs #define IN6P_LOCK(x) 126 1.1 rjs #define INP_UNLOCK(x) 127 1.1 rjs #define IN6P_UNLOCK(x) 128 1.1 rjs 129 1.1 rjs /* Congestion control switch table */ 130 1.1 rjs extern struct dccp_cc_sw cc_sw[]; 131 1.1 rjs 132 1.1 rjs int dccp_log_in_vain = 1; 133 1.1 rjs int dccp_do_feature_nego = 1; 134 1.1 rjs 135 1.1 rjs struct inpcbhead dccpb; /* from dccp_var.h */ 136 1.1 rjs #ifdef __FreeBSD__ 137 1.1 rjs struct inpcbinfo dccpbinfo; 138 1.1 rjs #else 139 1.1 rjs struct inpcbtable dccpbtable; 140 1.1 rjs #endif 141 1.1 rjs 142 1.1 rjs #ifndef DCCPBHASHSIZE 143 1.1 rjs #define DCCPBHASHSIZE 16 144 1.1 rjs #endif 145 1.1 rjs 146 1.1 rjs struct pool dccpcb_pool; 147 1.1 rjs 148 1.1 rjs u_long dccp_sendspace = 32768; 149 1.1 rjs u_long dccp_recvspace = 65536; 150 1.1 rjs 151 1.1 rjs struct dccpstat dccpstat; /* from dccp_var.h */ 152 1.1 rjs 153 1.1 rjs static struct dccpcb * dccp_close(struct dccpcb *); 154 1.1 rjs static int dccp_disconnect2(struct dccpcb *); 155 1.1 rjs int dccp_get_option(char *, int, int, char *,int); 156 1.1 rjs void dccp_parse_options(struct dccpcb *, char *, int); 157 1.1 rjs int dccp_remove_feature(struct dccpcb *, u_int8_t, u_int8_t); 158 1.1 rjs int dccp_add_feature_option(struct dccpcb *, u_int8_t, u_int8_t, char *, u_int8_t); 159 1.1 rjs void dccp_feature_neg(struct dccpcb *, u_int8_t, u_int8_t, u_int8_t, char *); 160 1.1 rjs void dccp_close_t(void *); 161 1.1 rjs void dccp_timewait_t(void *); 162 1.1 rjs 163 1.1 rjs /* Ack Vector functions */ 164 1.1 rjs #define DCCP_VECTORSIZE 512 /* initial ack and cwnd-vector size. Multiple of 8 ! */ 165 1.1 rjs void dccp_use_ackvector(struct dccpcb *); 166 1.1 rjs void dccp_update_ackvector(struct dccpcb *, u_int64_t); 167 1.1 rjs void dccp_increment_ackvector(struct dccpcb *, u_int64_t); 168 1.1 rjs u_int16_t dccp_generate_ackvector(struct dccpcb *, u_char *); 169 1.1 rjs u_char dccp_ackvector_state(struct dccpcb *, u_int64_t); 170 1.1 rjs 171 1.1 rjs /* 172 1.1 rjs * DCCP initialization 173 1.1 rjs */ 174 1.1 rjs void 175 1.1 rjs dccp_init(void) 176 1.1 rjs { 177 1.1 rjs pool_init(&dccpcb_pool, sizeof(struct dccpcb), 0, 0, 0, "dccpcbpl", 178 1.1 rjs NULL, IPL_SOFTNET); 179 1.1 rjs 180 1.25 ozaki inpcb_init(&dccpbtable, DCCPBHASHSIZE, DCCPBHASHSIZE); 181 1.1 rjs } 182 1.1 rjs 183 1.1 rjs void 184 1.20 maxv dccp_input(struct mbuf *m, int off, int proto) 185 1.1 rjs { 186 1.1 rjs int iphlen; 187 1.1 rjs struct ip *ip = NULL; 188 1.1 rjs struct dccphdr *dh; 189 1.1 rjs struct dccplhdr *dlh; 190 1.1 rjs struct inpcb *inp = NULL, *oinp = NULL; 191 1.1 rjs struct dccpcb *dp; 192 1.1 rjs struct ipovly *ipov = NULL; 193 1.1 rjs struct dccp_requesthdr *drqh; 194 1.1 rjs struct dccp_ackhdr *dah = NULL; 195 1.1 rjs struct dccp_acklhdr *dalh = NULL; 196 1.1 rjs struct dccp_resethdr *drth; 197 1.1 rjs struct socket *so; 198 1.1 rjs u_char *optp = NULL; 199 1.1 rjs struct mbuf *opts = 0; 200 1.1 rjs int len, data_off, extrah_len, optlen; 201 1.1 rjs /*struct ip save_ip;*/ 202 1.1 rjs char options[DCCP_MAX_OPTIONS]; 203 1.1 rjs char test[2]; 204 1.1 rjs u_int32_t cslen; 205 1.1 rjs dccp_seq seqnr, low_seqnr, high_seqnr; 206 1.1 rjs int isipv6 = 0; 207 1.1 rjs int is_shortseq; /* Is this shortseq packet? */ 208 1.1 rjs #ifdef INET6 209 1.1 rjs struct ip6_hdr *ip6 = NULL; 210 1.1 rjs #endif 211 1.1 rjs 212 1.20 maxv iphlen = off; 213 1.1 rjs 214 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP packet!\n")); 215 1.1 rjs 216 1.1 rjs dccpstat.dccps_ipackets++; 217 1.1 rjs dccpstat.dccps_ibytes += m->m_pkthdr.len; 218 1.1 rjs 219 1.1 rjs #ifdef INET6 220 1.1 rjs isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; 221 1.1 rjs #endif 222 1.1 rjs 223 1.1 rjs #ifdef INET6 224 1.1 rjs if (isipv6) { 225 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP ipv6 packet, iphlen = %u!\n", iphlen)); 226 1.1 rjs ip6 = mtod(m, struct ip6_hdr *); 227 1.19 maxv M_REGION_GET(dh, struct dccphdr *, m, iphlen, sizeof(*dh)); 228 1.1 rjs if (dh == NULL) { 229 1.1 rjs dccpstat.dccps_badlen++; 230 1.1 rjs return; 231 1.1 rjs } 232 1.1 rjs } else 233 1.1 rjs #endif 234 1.1 rjs { 235 1.1 rjs /* 236 1.1 rjs * Strip IP options, if any; should skip this, 237 1.1 rjs * make available to user, and use on returned packets, 238 1.1 rjs * but we don't yet have a way to check the checksum 239 1.1 rjs * with options still present. 240 1.1 rjs */ 241 1.1 rjs if (iphlen > sizeof (struct ip)) { 242 1.1 rjs DCCP_DEBUG((LOG_INFO, "Need to strip options\n")); 243 1.1 rjs #if 0 /* XXX */ 244 1.1 rjs ip_stripoptions(m, (struct mbuf *)0); 245 1.1 rjs #endif 246 1.1 rjs iphlen = sizeof(struct ip); 247 1.1 rjs } 248 1.1 rjs 249 1.1 rjs /* 250 1.1 rjs * Get IP and DCCP header together in first mbuf. 251 1.1 rjs */ 252 1.1 rjs ip = mtod(m, struct ip *); 253 1.19 maxv M_REGION_GET(dh, struct dccphdr *, m, iphlen, sizeof(*dh)); 254 1.1 rjs if (dh == NULL) { 255 1.1 rjs dccpstat.dccps_badlen++; 256 1.1 rjs return; 257 1.1 rjs } 258 1.1 rjs } 259 1.9 msaitoh dlh = (struct dccplhdr*)dh; 260 1.1 rjs is_shortseq = !dh->dh_x; 261 1.1 rjs 262 1.1 rjs if (!is_shortseq) { 263 1.1 rjs DCCP_DEBUG((LOG_INFO, 264 1.1 rjs "Header info: cslen = %u, off = %u, type = %u, reserved = %u, seq = %u.%lu\n", 265 1.1 rjs dlh->dh_cscov, dlh->dh_off, dlh->dh_type, dlh->dh_res, ntohs(dlh->dh_seq), 266 1.1 rjs (unsigned long)ntohl(dlh->dh_seq2))); 267 1.1 rjs } else { 268 1.1 rjs DCCP_DEBUG((LOG_INFO, 269 1.1 rjs "Header info(short): cslen = %u, off = %u, type = %u, reserved = %u, seq = %u\n", 270 1.1 rjs dh->dh_cscov, dh->dh_off, dh->dh_type, dh->dh_res, ntohl(dh->dh_seq))); 271 1.1 rjs } 272 1.1 rjs 273 1.1 rjs /* 274 1.1 rjs * Make mbuf data length reflect DCCP length. 275 1.1 rjs * If not enough data to reflect DCCP length, drop. 276 1.1 rjs */ 277 1.1 rjs 278 1.1 rjs #ifdef INET6 279 1.1 rjs if (isipv6) 280 1.1 rjs len = m->m_pkthdr.len - off; 281 1.1 rjs else 282 1.1 rjs #endif 283 1.1 rjs { 284 1.1 rjs len = ntohs(ip->ip_len); 285 1.1 rjs len -= ip->ip_hl << 2; 286 1.1 rjs } 287 1.1 rjs 288 1.1 rjs if (len < sizeof(struct dccphdr)) { 289 1.1 rjs DCCP_DEBUG((LOG_INFO, "Dropping DCCP packet!\n")); 290 1.1 rjs dccpstat.dccps_badlen++; 291 1.1 rjs goto badunlocked; 292 1.1 rjs } 293 1.1 rjs /* 294 1.1 rjs * Save a copy of the IP header in case we want restore it 295 1.1 rjs * for sending a DCCP reset packet in response. 296 1.1 rjs */ 297 1.1 rjs if (!isipv6) { 298 1.1 rjs /*save_ip = *ip;*/ 299 1.1 rjs ipov = (struct ipovly *)ip; 300 1.1 rjs } 301 1.1 rjs 302 1.1 rjs if (dh->dh_cscov == 0) { 303 1.1 rjs cslen = len; 304 1.1 rjs } else { 305 1.1 rjs cslen = dh->dh_off * 4 + (dh->dh_cscov - 1) * 4; 306 1.1 rjs if (cslen > len) 307 1.1 rjs cslen = len; 308 1.1 rjs } 309 1.1 rjs 310 1.1 rjs /* 311 1.1 rjs * Checksum extended DCCP header and data. 312 1.1 rjs */ 313 1.1 rjs 314 1.1 rjs #ifdef INET6 315 1.1 rjs if (isipv6) { 316 1.1 rjs if (in6_cksum(m, IPPROTO_DCCP, off, cslen) != 0) { 317 1.1 rjs dccpstat.dccps_badsum++; 318 1.1 rjs goto badunlocked; 319 1.1 rjs } 320 1.1 rjs } else 321 1.1 rjs #endif 322 1.1 rjs { 323 1.16 rjs memset(ipov->ih_x1, 0, sizeof(ipov->ih_x1)); 324 1.1 rjs ip->ip_len = htons(m->m_pkthdr.len); 325 1.1 rjs dh->dh_sum = in4_cksum(m, IPPROTO_DCCP, off, cslen); 326 1.1 rjs 327 1.1 rjs if (dh->dh_sum) { 328 1.1 rjs dccpstat.dccps_badsum++; 329 1.1 rjs goto badunlocked; 330 1.1 rjs } 331 1.1 rjs } 332 1.1 rjs 333 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 334 1.1 rjs 335 1.1 rjs /* 336 1.1 rjs * Locate pcb for datagram. 337 1.1 rjs */ 338 1.1 rjs #ifdef INET6 339 1.1 rjs if (isipv6) { 340 1.26 ozaki inp = in6pcb_lookup(&dccpbtable, &ip6->ip6_src, 341 1.1 rjs dh->dh_sport, &ip6->ip6_dst, dh->dh_dport, 0, 0); 342 1.23 ozaki if (inp == NULL) { 343 1.1 rjs /* XXX stats increment? */ 344 1.26 ozaki inp = in6pcb_lookup_bound(&dccpbtable, &ip6->ip6_dst, 345 1.1 rjs dh->dh_dport, 0); 346 1.1 rjs } 347 1.1 rjs } else 348 1.1 rjs #endif 349 1.1 rjs { 350 1.25 ozaki inp = inpcb_lookup(&dccpbtable, ip->ip_src, 351 1.1 rjs dh->dh_sport, ip->ip_dst, dh->dh_dport, 0); 352 1.1 rjs if (inp == NULL) { 353 1.1 rjs /* XXX stats increment? */ 354 1.25 ozaki inp = inpcb_lookup_bound(&dccpbtable, ip->ip_dst, 355 1.1 rjs dh->dh_dport); 356 1.1 rjs } 357 1.1 rjs } 358 1.1 rjs if (isipv6) { 359 1.23 ozaki DCCP_DEBUG((LOG_INFO, "in6p=%p\n", inp)); 360 1.1 rjs } else { 361 1.1 rjs DCCP_DEBUG((LOG_INFO, "inp=%p\n", inp)); 362 1.1 rjs } 363 1.1 rjs 364 1.23 ozaki if (inp == NULL) { 365 1.1 rjs if (dccp_log_in_vain) { 366 1.1 rjs #ifdef INET6 367 1.1 rjs char dbuf[INET6_ADDRSTRLEN+2], sbuf[INET6_ADDRSTRLEN+2]; 368 1.1 rjs #else 369 1.1 rjs char dbuf[4*sizeof "123"], sbuf[4*sizeof "123"]; 370 1.1 rjs #endif 371 1.1 rjs 372 1.1 rjs #ifdef INET6 373 1.1 rjs if (isipv6) { 374 1.11 ryo char ip6buf[INET6_ADDRSTRLEN]; 375 1.1 rjs strlcpy(dbuf, "[", sizeof dbuf); 376 1.12 christos strlcat(dbuf, IN6_PRINT(ip6buf, &ip6->ip6_dst), sizeof dbuf); 377 1.1 rjs strlcat(dbuf, "]", sizeof dbuf); 378 1.1 rjs strlcpy(sbuf, "[", sizeof sbuf); 379 1.12 christos strlcat(sbuf, IN6_PRINT(ip6buf, &ip6->ip6_src), sizeof sbuf); 380 1.1 rjs strlcat(sbuf, "]", sizeof sbuf); 381 1.1 rjs } else 382 1.1 rjs #endif 383 1.1 rjs { 384 1.1 rjs strlcpy(dbuf, inet_ntoa(ip->ip_dst), sizeof dbuf); 385 1.1 rjs strlcpy(sbuf, inet_ntoa(ip->ip_src), sizeof sbuf); 386 1.1 rjs } 387 1.1 rjs log(LOG_INFO, 388 1.1 rjs "Connection attempt to DCCP %s:%d from %s:%d\n", 389 1.1 rjs dbuf, ntohs(dh->dh_dport), sbuf, 390 1.1 rjs ntohs(dh->dh_sport)); 391 1.1 rjs } 392 1.1 rjs dccpstat.dccps_noport++; 393 1.1 rjs 394 1.1 rjs /* 395 1.1 rjs * We should send DCCP reset here but we can't call dccp_output 396 1.1 rjs * since we have no dccpcb. A icmp unreachable works great but 397 1.1 rjs * the specs says DCCP reset :( 398 1.1 rjs * 399 1.1 rjs * if (!isipv6) { 400 1.1 rjs * *ip = save_ip; 401 1.1 rjs * ip->ip_len += iphlen; 402 1.9 msaitoh * icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); 403 1.1 rjs * } 404 1.1 rjs */ 405 1.1 rjs 406 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 407 1.1 rjs goto badunlocked; 408 1.1 rjs } 409 1.1 rjs INP_LOCK(inp); 410 1.1 rjs 411 1.23 ozaki dp = intodccpcb(inp); 412 1.23 ozaki if (dp == NULL) { 413 1.1 rjs INP_UNLOCK(inp); 414 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 415 1.1 rjs goto badunlocked; 416 1.1 rjs } 417 1.1 rjs 418 1.1 rjs if (dp->state == DCCPS_CLOSED) { 419 1.1 rjs DCCP_DEBUG((LOG_INFO, "We are in closed state, dropping packet and sending reset!\n")); 420 1.1 rjs if (dh->dh_type != DCCP_TYPE_RESET) 421 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 422 1.1 rjs INP_UNLOCK(inp); 423 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 424 1.1 rjs goto badunlocked; 425 1.1 rjs } 426 1.1 rjs 427 1.23 ozaki so = inp->inp_socket; 428 1.1 rjs 429 1.1 rjs if (so->so_options & SO_ACCEPTCONN) { 430 1.1 rjs DCCP_DEBUG((LOG_INFO, "so->options & SO_ACCEPTCONN! dp->state = %i\n", dp->state)); 431 1.1 rjs so = sonewconn(so, SS_ISCONNECTED); 432 1.1 rjs if (so == 0) { 433 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, sonewconn failed!\n")); 434 1.1 rjs INP_UNLOCK(inp); 435 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 436 1.1 rjs goto badunlocked; 437 1.1 rjs } 438 1.1 rjs 439 1.1 rjs /* INP_LOCK(inp); XXX */ 440 1.1 rjs 441 1.23 ozaki oinp = inp; 442 1.1 rjs 443 1.1 rjs #ifdef INET6 444 1.1 rjs if (isipv6) { 445 1.23 ozaki inp = sotoinpcb(so); 446 1.24 ozaki in6p_laddr(inp) = ip6->ip6_dst; 447 1.24 ozaki in6p_faddr(inp) = ip6->ip6_src; 448 1.23 ozaki inp->inp_lport = dh->dh_dport; 449 1.23 ozaki inp->inp_fport = dh->dh_sport; 450 1.25 ozaki inpcb_set_state(inp, INP_CONNECTED); 451 1.1 rjs } else 452 1.1 rjs #endif 453 1.1 rjs { 454 1.1 rjs inp = sotoinpcb(so); 455 1.24 ozaki in4p_laddr(inp) = ip->ip_dst; 456 1.24 ozaki in4p_faddr(inp) = ip->ip_src; 457 1.1 rjs inp->inp_lport = dh->dh_dport; 458 1.1 rjs inp->inp_fport = dh->dh_sport; 459 1.1 rjs } 460 1.1 rjs 461 1.1 rjs if (!isipv6) 462 1.25 ozaki inpcb_set_state(inp, INP_BOUND); 463 1.1 rjs 464 1.23 ozaki dp = inp->inp_ppcb; 465 1.1 rjs 466 1.1 rjs dp->state = DCCPS_LISTEN; 467 1.1 rjs dp->who = DCCP_SERVER; 468 1.23 ozaki dp->cslen = ((struct dccpcb *)oinp->inp_ppcb)->cslen; 469 1.23 ozaki dp->avgpsize = ((struct dccpcb *)oinp->inp_ppcb)->avgpsize; 470 1.23 ozaki dp->scode = ((struct dccpcb *)oinp->inp_ppcb)->scode; 471 1.1 rjs dp->seq_snd = (((u_int64_t)random() << 32) | random()) % 281474976710656LL; 472 1.1 rjs dp->ref_seq.hi = dp->seq_snd >> 24; 473 1.1 rjs dp->ref_seq.lo = (u_int64_t)(dp->seq_snd & 0xffffff); 474 1.1 rjs INP_UNLOCK(oinp); 475 1.1 rjs DCCP_DEBUG((LOG_INFO, "New dp = %u, dp->state = %u!\n", (int)dp, dp->state)); 476 1.1 rjs } 477 1.1 rjs 478 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 479 1.1 rjs 480 1.1 rjs /* 481 1.1 rjs * Check if sequence number is inside the loss window 482 1.1 rjs */ 483 1.1 rjs if (!is_shortseq) { 484 1.1 rjs DHDR_TO_DSEQ(seqnr, dlh); 485 1.1 rjs } else { 486 1.1 rjs /* shortseq */ 487 1.1 rjs seqnr = CONVERT_TO_LONGSEQ((ntohl(dh->dh_seq) >> 8), dp->ref_pseq); 488 1.1 rjs DCCP_DEBUG((LOG_INFO, "short seq conversion %x, %u %u\n", 489 1.1 rjs ntohl(dh->dh_seq) >> 8, dp->ref_pseq.hi, dp->ref_pseq.lo)); 490 1.1 rjs } 491 1.1 rjs 492 1.1 rjs DCCP_DEBUG((LOG_INFO, "Received DCCP packet with sequence number = %llu , gsn_rcv %llu\n", seqnr, dp->gsn_rcv)); 493 1.1 rjs 494 1.1 rjs /* store ccval */ 495 1.1 rjs dp->ccval = dh->dh_ccval; 496 1.1 rjs 497 1.1 rjs if (dp->gsn_rcv == 281474976710656LL) dp->gsn_rcv = seqnr; 498 1.1 rjs if (dp->gsn_rcv > (dp->loss_window / 4)) 499 1.1 rjs low_seqnr = (dp->gsn_rcv - (dp->loss_window / 4)) % 281474976710656LL; 500 1.1 rjs else 501 1.1 rjs low_seqnr = 0ll; 502 1.1 rjs high_seqnr = (dp->gsn_rcv + (dp->loss_window / 4 * 3)) % 281474976710656LL; 503 1.1 rjs 504 1.1 rjs if (! (DCCP_SEQ_GT(seqnr, low_seqnr) && DCCP_SEQ_LT(seqnr, high_seqnr))) { 505 1.1 rjs dccpstat.dccps_badseq++; 506 1.17 dholland DCCP_DEBUG((LOG_INFO, "Received DCCP packet with bad sequence number = %llu (low_seqnr = %llu, high_seqnr = %llu)\n", seqnr, low_seqnr, high_seqnr)); 507 1.1 rjs INP_UNLOCK(inp); 508 1.1 rjs goto badunlocked; 509 1.1 rjs } 510 1.1 rjs 511 1.1 rjs /* dp->gsn_rcv should always be the highest received valid sequence number */ 512 1.1 rjs if (DCCP_SEQ_GT(seqnr, dp->gsn_rcv)) 513 1.1 rjs dp->gsn_rcv = seqnr; 514 1.1 rjs 515 1.1 rjs /* Just ignore DCCP-Move for now */ 516 1.1 rjs if (dlh->dh_type == DCCP_TYPE_DATA) { 517 1.1 rjs extrah_len = 0; 518 1.1 rjs if (!is_shortseq) 519 1.1 rjs optp = (u_char *)(dlh + 1); 520 1.1 rjs else 521 1.1 rjs optp = (u_char *)(dh + 1); 522 1.1 rjs } else if (dh->dh_type == DCCP_TYPE_REQUEST) { 523 1.1 rjs drqh = (struct dccp_requesthdr *)(dlh + 1); 524 1.1 rjs if (drqh->drqh_scode != dp->scode){ 525 1.1 rjs DCCP_DEBUG((LOG_INFO, "service code in request packet doesn't match! %x %x\n", drqh->drqh_scode, dp->scode)); 526 1.1 rjs INP_UNLOCK(inp); 527 1.1 rjs dp->state = DCCPS_SERVER_CLOSE; /* So disconnect2 doesn't send CLOSEREQ */ 528 1.1 rjs dccp_disconnect2(dp); 529 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 530 1.1 rjs dccp_close(dp); 531 1.1 rjs goto badunlocked; 532 1.1 rjs } 533 1.1 rjs optp = (u_char *)(drqh + 1); 534 1.1 rjs extrah_len = 4; 535 1.1 rjs 536 1.1 rjs /* store reference peer sequence number */ 537 1.1 rjs dp->ref_pseq.hi = seqnr >> 24; 538 1.1 rjs dp->ref_pseq.lo = (u_int64_t)(seqnr & 0xffffff); 539 1.1 rjs 540 1.1 rjs } else if (dh->dh_type == DCCP_TYPE_RESET) { 541 1.1 rjs extrah_len = 8 ; 542 1.1 rjs drth = (struct dccp_resethdr *)(dlh + 1); 543 1.1 rjs optp = (u_char *)(drth + 1); 544 1.1 rjs } else { 545 1.1 rjs if (!is_shortseq){ 546 1.1 rjs extrah_len = 8; 547 1.1 rjs dalh = (struct dccp_acklhdr *)(dlh + 1); 548 1.1 rjs if (dh->dh_type == DCCP_TYPE_RESPONSE) { 549 1.1 rjs extrah_len += 4; 550 1.1 rjs drqh = (struct dccp_requesthdr *)(dalh + 1); 551 1.1 rjs if (drqh->drqh_scode != dp->scode){ 552 1.1 rjs DCCP_DEBUG((LOG_INFO, "service code in response packet doesn't match! %x %x\n", drqh->drqh_scode, dp->scode)); 553 1.1 rjs INP_UNLOCK(inp); 554 1.1 rjs dp->state = DCCPS_CLIENT_CLOSE; /* So disconnect2 doesn't send CLOSEREQ */ 555 1.1 rjs dccp_disconnect2(dp); 556 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 557 1.1 rjs dccp_close(dp); 558 1.1 rjs goto badunlocked; 559 1.1 rjs } 560 1.1 rjs optp = (u_char *)(drqh + 1); 561 1.1 rjs 562 1.1 rjs /* store reference peer sequence number */ 563 1.1 rjs dp->ref_pseq.hi = seqnr >> 24; 564 1.1 rjs dp->ref_pseq.lo = (u_int64_t)(seqnr & 0xffffff); 565 1.1 rjs } else 566 1.1 rjs optp = (u_char *)(dalh + 1); 567 1.1 rjs } else { 568 1.1 rjs extrah_len = 4; 569 1.1 rjs dah = (struct dccp_ackhdr *)(dh + 1); 570 1.1 rjs optp = (u_char *)(dah + 1); 571 1.1 rjs } 572 1.1 rjs 573 1.1 rjs } 574 1.1 rjs 575 1.1 rjs data_off = (dh->dh_off << 2); 576 1.1 rjs 577 1.1 rjs dp->seq_rcv = seqnr; 578 1.1 rjs dp->ack_rcv = 0; /* Clear it for now */ 579 1.1 rjs dp->type_rcv = dh->dh_type; 580 1.1 rjs dp->len_rcv = m->m_len - data_off - iphlen; /* Correct length ? */ 581 1.1 rjs 582 1.1 rjs if (!is_shortseq) 583 1.1 rjs optlen = data_off - (sizeof(struct dccplhdr) + extrah_len); 584 1.1 rjs else 585 1.1 rjs optlen = data_off - (sizeof(struct dccphdr) + extrah_len); 586 1.1 rjs 587 1.1 rjs if (optlen < 0) { 588 1.1 rjs DCCP_DEBUG((LOG_INFO, "Data offset is smaller then it could be, optlen = %i data_off = %i, m_len = %i, iphlen = %i extrah_len = %i !\n", optlen, data_off, m->m_len, iphlen, extrah_len)); 589 1.1 rjs INP_UNLOCK(inp); 590 1.1 rjs goto badunlocked; 591 1.1 rjs } 592 1.1 rjs 593 1.1 rjs if (optlen > 0) { 594 1.1 rjs if (optlen > DCCP_MAX_OPTIONS) { 595 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, more options (%i) then DCCP_MAX_OPTIONS options!\n", optlen)); 596 1.1 rjs INP_UNLOCK(inp); 597 1.1 rjs goto badunlocked; 598 1.1 rjs } 599 1.1 rjs 600 1.1 rjs DCCP_DEBUG((LOG_INFO, "Parsing DCCP options, optlen = %i\n", optlen)); 601 1.16 rjs memcpy(options, optp, optlen); 602 1.1 rjs dccp_parse_options(dp, options, optlen); 603 1.1 rjs } 604 1.1 rjs 605 1.1 rjs DCCP_DEBUG((LOG_INFO, "BEFORE state check, Got a %u packet while in %u state, who = %u!\n", dh->dh_type, dp->state, dp->who)); 606 1.1 rjs 607 1.1 rjs if (dp->state == DCCPS_LISTEN) { 608 1.1 rjs switch (dh->dh_type) { 609 1.1 rjs 610 1.1 rjs case DCCP_TYPE_REQUEST: 611 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP REQUEST\n")); 612 1.1 rjs dp->state = DCCPS_REQUEST; 613 1.1 rjs if (dp->cc_in_use[1] < 0) { 614 1.1 rjs test[0] = DEFAULT_CCID; 615 1.1 rjs test[1] = 3; 616 1.1 rjs dccp_add_feature(dp, DCCP_OPT_CHANGE_R, DCCP_FEATURE_CC, test, 2); 617 1.1 rjs } 618 1.1 rjs if (len > data_off) { 619 1.1 rjs DCCP_DEBUG((LOG_INFO, "XXX: len=%d, data_off=%d\n", len, data_off)); 620 1.1 rjs dccp_add_option(dp, DCCP_OPT_DATA_DISCARD, test, 0); 621 1.1 rjs } 622 1.1 rjs callout_reset(&dp->connect_timer, DCCP_CONNECT_TIMER, 623 1.1 rjs dccp_connect_t, dp); 624 1.1 rjs dccp_output(dp, 0); 625 1.1 rjs break; 626 1.1 rjs 627 1.1 rjs 628 1.1 rjs /* These are ok if the sender has a valid init Cookie */ 629 1.1 rjs case DCCP_TYPE_ACK: 630 1.1 rjs case DCCP_TYPE_DATAACK: 631 1.1 rjs case DCCP_TYPE_DATA: 632 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP ACK/DATAACK/DATA, should check init cookie...\n")); 633 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 634 1.1 rjs break; 635 1.1 rjs 636 1.1 rjs case DCCP_TYPE_RESET: 637 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP RESET\n")); 638 1.1 rjs dp->state = DCCPS_TIME_WAIT; 639 1.1 rjs dp = dccp_close(dp); 640 1.1 rjs return; 641 1.1 rjs 642 1.1 rjs default: 643 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in listen stage!\n", dh->dh_type)); 644 1.1 rjs /* Force send reset. */ 645 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 646 1.1 rjs } 647 1.1 rjs } else if (dp->state == DCCPS_REQUEST) { 648 1.1 rjs switch (dh->dh_type) { 649 1.1 rjs case DCCP_TYPE_RESPONSE: 650 1.1 rjs DAHDR_TO_DSEQ(dp->ack_rcv, ((struct dccp_acklhdr*)dalh)->dash); 651 1.1 rjs dp->ack_snd = dp->seq_rcv; 652 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP REPSONSE %x %llx\n", dp, dp->ack_snd)); 653 1.1 rjs 654 1.1 rjs callout_stop(&dp->retrans_timer); 655 1.1 rjs callout_stop(&dp->connect_timer); 656 1.1 rjs 657 1.1 rjs /* First check if we have negotiated a cc */ 658 1.1 rjs if (dp->cc_in_use[0] > 0 && dp->cc_in_use[1] > 0) { 659 1.1 rjs DCCP_DEBUG((LOG_INFO, "Setting DCCPS_ESTAB & soisconnected\n")); 660 1.1 rjs dp->state = DCCPS_ESTAB; 661 1.1 rjs dccpstat.dccps_connects++; 662 1.23 ozaki soisconnected(inp->inp_socket); 663 1.1 rjs } else { 664 1.1 rjs dp->state = DCCPS_RESPOND; 665 1.1 rjs DCCP_DEBUG((LOG_INFO, "CC negotiation is not finished, cc_in_use[0] = %u, cc_in_use[1] = %u\n",dp->cc_in_use[0], dp->cc_in_use[1])); 666 1.1 rjs 667 1.1 rjs } 668 1.1 rjs dccp_output(dp, 0); 669 1.1 rjs break; 670 1.1 rjs 671 1.1 rjs case DCCP_TYPE_RESET: 672 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP RESET\n")); 673 1.1 rjs dp->state = DCCPS_TIME_WAIT; 674 1.1 rjs dp = dccp_close(dp); 675 1.1 rjs return; 676 1.1 rjs 677 1.1 rjs default: 678 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in REQUEST stage!\n", dh->dh_type)); 679 1.1 rjs /* Force send reset. */ 680 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 681 1.1 rjs if (dh->dh_type == DCCP_TYPE_CLOSE) { 682 1.1 rjs dp = dccp_close(dp); 683 1.1 rjs return; 684 1.1 rjs } else { 685 1.1 rjs callout_stop(&dp->retrans_timer); 686 1.1 rjs dp->state = DCCPS_TIME_WAIT; 687 1.1 rjs } 688 1.1 rjs } 689 1.1 rjs } else if (dp->state == DCCPS_RESPOND) { 690 1.1 rjs switch (dh->dh_type) { 691 1.1 rjs 692 1.1 rjs case DCCP_TYPE_REQUEST: 693 1.1 rjs break; 694 1.1 rjs case DCCP_TYPE_ACK: 695 1.1 rjs case DCCP_TYPE_DATAACK: 696 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP ACK/DATAACK\n")); 697 1.1 rjs 698 1.1 rjs callout_stop(&dp->connect_timer); 699 1.1 rjs 700 1.1 rjs if (!is_shortseq) { 701 1.1 rjs DAHDR_TO_DSEQ(dp->ack_rcv, ((struct dccp_acklhdr*)dalh)->dash); 702 1.1 rjs } else { 703 1.1 rjs /* shortseq XXX */ 704 1.1 rjs dp->ack_rcv = CONVERT_TO_LONGSEQ((ntohl(dah->dash.dah_ack) >> 8), dp->ref_seq); 705 1.1 rjs } 706 1.1 rjs 707 1.1 rjs if (dp->cc_in_use[0] > 0 && dp->cc_in_use[1] > 0) { 708 1.1 rjs DCCP_DEBUG((LOG_INFO, "Setting DCCPS_ESTAB & soisconnected\n")); 709 1.1 rjs dp->state = DCCPS_ESTAB; 710 1.1 rjs dccpstat.dccps_connects++; 711 1.23 ozaki soisconnected(inp->inp_socket); 712 1.1 rjs } else { 713 1.1 rjs DCCP_DEBUG((LOG_INFO, "CC negotiation is not finished, cc_in_use[0] = %u, cc_in_use[1] = %u\n",dp->cc_in_use[0], dp->cc_in_use[1])); 714 1.1 rjs /* Force an output!!! */ 715 1.1 rjs dp->ack_snd = dp->seq_rcv; 716 1.1 rjs dccp_output(dp, 0); 717 1.1 rjs } 718 1.1 rjs 719 1.1 rjs if (dh->dh_type == DCCP_TYPE_DATAACK && dp->cc_in_use[1] > 0) { 720 1.1 rjs if (!dp->ack_snd) dp->ack_snd = dp->seq_rcv; 721 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling *cc_sw[%u].cc_recv_packet_recv!\n", dp->cc_in_use[1])); 722 1.9 msaitoh (*cc_sw[dp->cc_in_use[1]].cc_recv_packet_recv)(dp->cc_state[1], options, optlen); 723 1.1 rjs } 724 1.1 rjs break; 725 1.1 rjs 726 1.1 rjs case DCCP_TYPE_CLOSE: 727 1.1 rjs dccp_output(dp, DCCP_TYPE_CLOSE + 1); 728 1.1 rjs dp = dccp_close(dp); 729 1.1 rjs goto badunlocked; 730 1.1 rjs 731 1.1 rjs case DCCP_TYPE_RESET: 732 1.1 rjs dp->state = DCCPS_TIME_WAIT; 733 1.1 rjs callout_stop(&dp->retrans_timer); 734 1.1 rjs break; 735 1.1 rjs 736 1.1 rjs default: 737 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in response stage!\n", dh->dh_type)); 738 1.1 rjs /* Force send reset. */ 739 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 740 1.1 rjs } 741 1.1 rjs } else if (dp->state == DCCPS_ESTAB) { 742 1.1 rjs switch (dh->dh_type) { 743 1.1 rjs 744 1.1 rjs case DCCP_TYPE_DATA: 745 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP DATA, state = %i, cc_in_use[1] = %u\n", dp->state, dp->cc_in_use[1])); 746 1.1 rjs 747 1.1 rjs if (dp->cc_in_use[1] > 0) { 748 1.1 rjs if (!dp->ack_snd) dp->ack_snd = dp->seq_rcv; 749 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling data *cc_sw[%u].cc_recv_packet_recv! %llx %llx dp=%x\n", dp->cc_in_use[1], dp->ack_snd, dp->seq_rcv, dp)); 750 1.1 rjs (*cc_sw[dp->cc_in_use[1]].cc_recv_packet_recv)(dp->cc_state[1], options, optlen); 751 1.1 rjs } 752 1.1 rjs break; 753 1.1 rjs 754 1.1 rjs case DCCP_TYPE_ACK: 755 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP ACK\n")); 756 1.1 rjs if (!is_shortseq) { 757 1.1 rjs DAHDR_TO_DSEQ(dp->ack_rcv, ((struct dccp_acklhdr*)dalh)->dash); 758 1.1 rjs } else { 759 1.1 rjs /* shortseq */ 760 1.1 rjs dp->ack_rcv = CONVERT_TO_LONGSEQ((ntohl(dah->dash.dah_ack) >> 8), dp->ref_seq); 761 1.1 rjs } 762 1.1 rjs 763 1.1 rjs if (dp->cc_in_use[1] > 0) { 764 1.1 rjs /* This is called so Acks on Acks can be handled */ 765 1.1 rjs if (!dp->ack_snd) dp->ack_snd = dp->seq_rcv; 766 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling ACK *cc_sw[%u].cc_recv_packet_recv! %llx %llx\n", dp->cc_in_use[1], dp->ack_snd, dp->seq_rcv)); 767 1.9 msaitoh (*cc_sw[dp->cc_in_use[1]].cc_recv_packet_recv)(dp->cc_state[1], options, optlen); 768 1.1 rjs } 769 1.1 rjs break; 770 1.1 rjs 771 1.1 rjs case DCCP_TYPE_DATAACK: 772 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP DATAACK\n")); 773 1.1 rjs 774 1.1 rjs if (!is_shortseq) { 775 1.1 rjs DAHDR_TO_DSEQ(dp->ack_rcv, ((struct dccp_acklhdr*)dalh)->dash); 776 1.1 rjs } else { 777 1.1 rjs /* shortseq */ 778 1.1 rjs dp->ack_rcv = CONVERT_TO_LONGSEQ((ntohl(dah->dash.dah_ack) >> 8), dp->ref_seq); 779 1.1 rjs } 780 1.1 rjs 781 1.1 rjs if (dp->cc_in_use[1] > 0) { 782 1.1 rjs if (!dp->ack_snd) dp->ack_snd = dp->seq_rcv; 783 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling *cc_sw[%u].cc_recv_packet_recv! %llx %llx\n", dp->cc_in_use[1], dp->ack_snd, dp->seq_rcv)); 784 1.9 msaitoh (*cc_sw[dp->cc_in_use[1]].cc_recv_packet_recv)(dp->cc_state[1], options, optlen); 785 1.1 rjs } 786 1.1 rjs break; 787 1.1 rjs 788 1.1 rjs case DCCP_TYPE_CLOSEREQ: 789 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP CLOSEREQ, state = estab\n")); 790 1.1 rjs if (dp->who == DCCP_CLIENT) { 791 1.1 rjs dccp_disconnect2(dp); 792 1.1 rjs } else { 793 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 794 1.1 rjs } 795 1.1 rjs break; 796 1.1 rjs 797 1.1 rjs case DCCP_TYPE_CLOSE: 798 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP CLOSE, state = estab\n")); 799 1.1 rjs dp->state = DCCPS_SERVER_CLOSE; /* So disconnect2 doesn't send CLOSEREQ */ 800 1.1 rjs dccp_disconnect2(dp); 801 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 802 1.1 rjs dccp_close(dp); 803 1.1 rjs goto badunlocked; 804 1.1 rjs break; 805 1.1 rjs 806 1.1 rjs case DCCP_TYPE_RESET: 807 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP RESET\n")); 808 1.1 rjs dp->state = DCCPS_TIME_WAIT; 809 1.1 rjs callout_stop(&dp->retrans_timer); 810 1.1 rjs callout_reset(&dp->timewait_timer, DCCP_TIMEWAIT_TIMER, 811 1.1 rjs dccp_timewait_t, dp); 812 1.1 rjs break; 813 1.1 rjs 814 1.1 rjs case DCCP_TYPE_MOVE: 815 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP MOVE\n")); 816 1.1 rjs break; 817 1.1 rjs 818 1.1 rjs default: 819 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in established stage!\n", dh->dh_type)); 820 1.1 rjs } 821 1.1 rjs 822 1.1 rjs } else if (dp->state == DCCPS_SERVER_CLOSE) { 823 1.1 rjs /* Server */ 824 1.1 rjs switch (dh->dh_type) { 825 1.1 rjs case DCCP_TYPE_CLOSE: 826 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP CLOSE (State DCCPS_SERVER_CLOSE)\n")); 827 1.1 rjs callout_stop(&dp->retrans_timer); 828 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 829 1.1 rjs dp = dccp_close(dp); 830 1.1 rjs goto badunlocked; 831 1.1 rjs 832 1.1 rjs case DCCP_TYPE_RESET: 833 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP RESET\n")); 834 1.1 rjs callout_stop(&dp->retrans_timer); 835 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 836 1.1 rjs dp->state = DCCPS_TIME_WAIT; 837 1.1 rjs break; 838 1.1 rjs default: 839 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in server_close stage!\n", dh->dh_type)); 840 1.1 rjs } 841 1.1 rjs 842 1.1 rjs } else if (dp->state == DCCPS_CLIENT_CLOSE) { 843 1.1 rjs /* Client */ 844 1.1 rjs switch (dh->dh_type) { 845 1.1 rjs case DCCP_TYPE_CLOSE: 846 1.1 rjs /* Ignore */ 847 1.1 rjs break; 848 1.1 rjs case DCCP_TYPE_CLOSEREQ: 849 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP CLOSEREQ, state = DCCPS_CLIENT_CLOSE\n")); 850 1.1 rjs /* Just resend close */ 851 1.1 rjs dccp_output(dp, 0); 852 1.1 rjs break; 853 1.1 rjs case DCCP_TYPE_RESET: 854 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP RESET\n")); 855 1.1 rjs callout_stop(&dp->retrans_timer); 856 1.1 rjs dp->state = DCCPS_TIME_WAIT; 857 1.1 rjs callout_reset(&dp->timewait_timer, DCCP_TIMEWAIT_TIMER, 858 1.1 rjs dccp_timewait_t, dp); 859 1.1 rjs break; 860 1.1 rjs default: 861 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in client_close stage!\n", dh->dh_type)); 862 1.1 rjs 863 1.1 rjs } 864 1.1 rjs } else { 865 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a %u packet while in %u state!\n", dh->dh_type, dp->state)); 866 1.1 rjs if (dh->dh_type != DCCP_TYPE_RESET) { 867 1.1 rjs /* Force send reset. */ 868 1.1 rjs DCCP_DEBUG((LOG_INFO, "Force sending a request!\n")); 869 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 870 1.1 rjs } 871 1.1 rjs } 872 1.1 rjs 873 1.1 rjs if (dh->dh_type == DCCP_TYPE_DATA || 874 1.1 rjs dh->dh_type == DCCP_TYPE_ACK || 875 1.1 rjs dh->dh_type == DCCP_TYPE_DATAACK) { 876 1.1 rjs if (dp->cc_in_use[0] > 0) { 877 1.1 rjs (*cc_sw[dp->cc_in_use[0]].cc_send_packet_recv)(dp->cc_state[0],options, optlen); 878 1.1 rjs } 879 1.1 rjs 880 1.1 rjs } 881 1.1 rjs 882 1.1 rjs if (dh->dh_type == DCCP_TYPE_DATA || dh->dh_type == DCCP_TYPE_DATAACK) { 883 1.27 rin if (so->so_state & SS_CANTRCVMORE) { 884 1.1 rjs DCCP_DEBUG((LOG_INFO, "state & SS_CANTRCVMORE...!\n")); 885 1.1 rjs m_freem(m); 886 1.27 rin m_freem(opts); 887 1.1 rjs } else { 888 1.1 rjs m_adj(m, (iphlen + data_off)); 889 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling sbappend!\n")); 890 1.1 rjs sbappend(&so->so_rcv, m); 891 1.1 rjs } 892 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling sorwakeup...!\n")); 893 1.1 rjs sorwakeup(so); 894 1.1 rjs } else { 895 1.1 rjs m_freem(m); 896 1.27 rin m_freem(opts); 897 1.1 rjs } 898 1.1 rjs #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 899 1.1 rjs if (dp) 900 1.1 rjs INP_UNLOCK(inp); 901 1.1 rjs #endif 902 1.1 rjs 903 1.1 rjs return; 904 1.1 rjs 905 1.1 rjs badunlocked: 906 1.1 rjs m_freem(m); 907 1.27 rin m_freem(opts); 908 1.1 rjs return; 909 1.1 rjs } 910 1.1 rjs 911 1.1 rjs /* 912 1.1 rjs * Notify a dccp user of an asynchronous error; 913 1.1 rjs * just wake up so that he can collect error status. 914 1.1 rjs */ 915 1.1 rjs void 916 1.1 rjs dccp_notify(struct inpcb *inp, int errno) 917 1.1 rjs { 918 1.1 rjs inp->inp_socket->so_error = errno; 919 1.1 rjs sorwakeup(inp->inp_socket); 920 1.1 rjs sowwakeup(inp->inp_socket); 921 1.1 rjs return; 922 1.1 rjs } 923 1.1 rjs 924 1.1 rjs /* 925 1.22 andvar * Called when we get ICMP errors (destination unreachable, 926 1.1 rjs * parameter problem, source quench, time exceeded and redirects) 927 1.1 rjs */ 928 1.1 rjs void * 929 1.1 rjs dccp_ctlinput(int cmd, const struct sockaddr *sa, void *vip) 930 1.1 rjs { 931 1.1 rjs struct ip *ip = vip; 932 1.1 rjs struct dccphdr *dh; 933 1.1 rjs void (*notify)(struct inpcb *, int) = dccp_notify; 934 1.1 rjs struct in_addr faddr; 935 1.1 rjs struct inpcb *inp = NULL; 936 1.1 rjs 937 1.1 rjs faddr = ((const struct sockaddr_in *)sa)->sin_addr; 938 1.1 rjs if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) 939 1.1 rjs return NULL; 940 1.1 rjs 941 1.1 rjs if (PRC_IS_REDIRECT(cmd)) { 942 1.1 rjs ip = 0; 943 1.25 ozaki notify = inpcb_rtchange; 944 1.1 rjs } else if (cmd == PRC_HOSTDEAD) 945 1.1 rjs ip = 0; 946 1.1 rjs else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) 947 1.1 rjs return NULL; 948 1.1 rjs if (ip) { 949 1.1 rjs /*s = splsoftnet();*/ 950 1.1 rjs dh = (struct dccphdr *)((vaddr_t)ip + (ip->ip_hl << 2)); 951 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 952 1.25 ozaki inpcb_notify(&dccpbtable, faddr, dh->dh_dport, 953 1.9 msaitoh ip->ip_src, dh->dh_sport, inetctlerrmap[cmd], notify); 954 1.1 rjs if (inp != NULL) { 955 1.1 rjs INP_LOCK(inp); 956 1.1 rjs if (inp->inp_socket != NULL) { 957 1.1 rjs (*notify)(inp, inetctlerrmap[cmd]); 958 1.1 rjs } 959 1.1 rjs INP_UNLOCK(inp); 960 1.1 rjs } 961 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 962 1.1 rjs /*splx(s);*/ 963 1.1 rjs } else 964 1.25 ozaki inpcb_notifyall(&dccpbtable, faddr, inetctlerrmap[cmd], notify); 965 1.1 rjs 966 1.1 rjs return NULL; 967 1.1 rjs } 968 1.1 rjs 969 1.1 rjs static int 970 1.1 rjs dccp_optsset(struct dccpcb *dp, struct sockopt *sopt) 971 1.1 rjs { 972 1.1 rjs int optval; 973 1.1 rjs int error = 0; 974 1.1 rjs 975 1.1 rjs switch (sopt->sopt_name) { 976 1.1 rjs case DCCP_CCID: 977 1.1 rjs error = sockopt_getint(sopt, &optval); 978 1.1 rjs /* Add check that optval is a CCID we support!!! */ 979 1.1 rjs if (optval == 2 || optval == 3 || optval == 0) { 980 1.1 rjs dp->pref_cc = optval; 981 1.1 rjs } else { 982 1.1 rjs error = EINVAL; 983 1.1 rjs } 984 1.1 rjs break; 985 1.1 rjs case DCCP_CSLEN: 986 1.1 rjs error = sockopt_getint(sopt, &optval); 987 1.1 rjs if (optval > 15 || optval < 0) { 988 1.1 rjs error = EINVAL; 989 1.1 rjs } else { 990 1.1 rjs dp->cslen = optval; 991 1.1 rjs } 992 1.1 rjs break; 993 1.1 rjs case DCCP_MAXSEG: 994 1.1 rjs error = sockopt_getint(sopt, &optval); 995 1.1 rjs if (optval > 0 && optval <= dp->d_maxseg) { 996 1.1 rjs dp->d_maxseg = optval; 997 1.1 rjs } else { 998 1.1 rjs error = EINVAL; 999 1.1 rjs } 1000 1.1 rjs break; 1001 1.1 rjs case DCCP_SERVICE: 1002 1.1 rjs error = sockopt_getint(sopt, &optval); 1003 1.1 rjs dp->scode = optval; 1004 1.1 rjs break; 1005 1.1 rjs 1006 1.1 rjs default: 1007 1.1 rjs error = ENOPROTOOPT; 1008 1.1 rjs } 1009 1.1 rjs 1010 1.1 rjs return error; 1011 1.1 rjs } 1012 1.1 rjs 1013 1.1 rjs static int 1014 1.1 rjs dccp_optsget(struct dccpcb *dp, struct sockopt *sopt) 1015 1.1 rjs { 1016 1.1 rjs int optval = 0; 1017 1.1 rjs int error = 0; 1018 1.1 rjs 1019 1.1 rjs switch (sopt->sopt_name) { 1020 1.1 rjs case DCCP_CCID: 1021 1.1 rjs optval = dp->pref_cc; 1022 1.1 rjs error = sockopt_set(sopt, &optval, sizeof(optval)); 1023 1.1 rjs break; 1024 1.1 rjs case DCCP_CSLEN: 1025 1.1 rjs optval = dp->cslen; 1026 1.1 rjs error = sockopt_set(sopt, &optval, sizeof(optval)); 1027 1.1 rjs break; 1028 1.1 rjs case DCCP_MAXSEG: 1029 1.1 rjs optval = dp->d_maxseg; 1030 1.1 rjs error = sockopt_set(sopt, &optval, sizeof(optval)); 1031 1.1 rjs break; 1032 1.1 rjs case DCCP_SERVICE: 1033 1.1 rjs optval = dp->scode; 1034 1.1 rjs error = sockopt_set(sopt, &optval, sizeof(optval)); 1035 1.1 rjs break; 1036 1.1 rjs default: 1037 1.1 rjs error = ENOPROTOOPT; 1038 1.1 rjs } 1039 1.1 rjs 1040 1.1 rjs return error; 1041 1.1 rjs } 1042 1.1 rjs 1043 1.1 rjs /* 1044 1.1 rjs * Called by getsockopt and setsockopt. 1045 1.1 rjs * 1046 1.1 rjs */ 1047 1.1 rjs int 1048 1.1 rjs dccp_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1049 1.1 rjs { 1050 1.1 rjs int s, error = 0; 1051 1.1 rjs struct inpcb *inp; 1052 1.1 rjs struct dccpcb *dp; 1053 1.1 rjs int family; /* family of the socket */ 1054 1.1 rjs 1055 1.1 rjs family = so->so_proto->pr_domain->dom_family; 1056 1.1 rjs error = 0; 1057 1.1 rjs 1058 1.1 rjs s = splsoftnet(); 1059 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 1060 1.23 ozaki inp = sotoinpcb(so); 1061 1.1 rjs if (inp == NULL) 1062 1.1 rjs { 1063 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 1064 1.1 rjs splx(s); 1065 1.1 rjs return (ECONNRESET); 1066 1.1 rjs } 1067 1.1 rjs /* 1068 1.1 rjs if (inp) 1069 1.1 rjs INP_LOCK(inp); 1070 1.1 rjs else 1071 1.1 rjs IN6P_LOCK(in6p); 1072 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 1073 1.1 rjs */ 1074 1.1 rjs if (sopt->sopt_level != IPPROTO_DCCP) { 1075 1.1 rjs switch (family) { 1076 1.1 rjs case PF_INET: 1077 1.1 rjs error = ip_ctloutput(op, so, sopt); 1078 1.1 rjs break; 1079 1.1 rjs #if defined(INET6) 1080 1.1 rjs case PF_INET6: 1081 1.1 rjs error = ip6_ctloutput(op, so, sopt); 1082 1.1 rjs break; 1083 1.1 rjs #endif 1084 1.1 rjs } 1085 1.1 rjs splx(s); 1086 1.1 rjs return (error); 1087 1.1 rjs } 1088 1.1 rjs 1089 1.23 ozaki dp = intodccpcb(inp); 1090 1.1 rjs 1091 1.1 rjs if (op == PRCO_SETOPT) { 1092 1.1 rjs error = dccp_optsset(dp, sopt); 1093 1.1 rjs } else if (op == PRCO_GETOPT) { 1094 1.1 rjs error = dccp_optsget(dp, sopt); 1095 1.1 rjs } else { 1096 1.1 rjs error = EINVAL; 1097 1.1 rjs } 1098 1.1 rjs /* 1099 1.1 rjs if (inp) 1100 1.1 rjs INP_UNLOCK(inp); 1101 1.1 rjs else 1102 1.1 rjs IN6P_UNLOCK(in6p); 1103 1.1 rjs */ 1104 1.1 rjs splx(s); 1105 1.1 rjs return error; 1106 1.1 rjs } 1107 1.1 rjs 1108 1.1 rjs int 1109 1.1 rjs dccp_output(struct dccpcb *dp, u_int8_t extra) 1110 1.1 rjs { 1111 1.1 rjs struct inpcb *inp; 1112 1.1 rjs struct socket *so; 1113 1.1 rjs struct mbuf *m; 1114 1.1 rjs 1115 1.1 rjs struct ip *ip = NULL; 1116 1.1 rjs struct dccphdr *dh; 1117 1.1 rjs struct dccplhdr *dlh; 1118 1.1 rjs struct dccp_requesthdr *drqh; 1119 1.1 rjs struct dccp_ackhdr *dah; 1120 1.1 rjs struct dccp_acklhdr *dalh; 1121 1.1 rjs struct dccp_resethdr *drth; 1122 1.1 rjs u_char *optp = NULL; 1123 1.1 rjs int error = 0; 1124 1.1 rjs int off, sendalot, t, i; 1125 1.1 rjs u_int32_t hdrlen, optlen, extrah_len, cslen; 1126 1.1 rjs u_int8_t type; 1127 1.1 rjs char options[DCCP_MAX_OPTIONS *2]; 1128 1.1 rjs long len, pktlen; 1129 1.1 rjs int isipv6 = 0; 1130 1.1 rjs int use_shortseq = 0; 1131 1.1 rjs #ifdef INET6 1132 1.1 rjs struct ip6_hdr *ip6 = NULL; 1133 1.1 rjs #endif 1134 1.1 rjs 1135 1.1 rjs DCCP_DEBUG((LOG_INFO, "dccp_output start!\n")); 1136 1.1 rjs 1137 1.1 rjs isipv6 = (dp->inp_vflag & INP_IPV6) != 0; 1138 1.1 rjs 1139 1.1 rjs DCCP_DEBUG((LOG_INFO, "Going to send a DCCP packet!\n")); 1140 1.1 rjs #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 1141 1.1 rjs KASSERT(mutex_assert(&dp->d_inpcb->inp_mtx, MA_OWNED)); 1142 1.1 rjs #endif 1143 1.1 rjs 1144 1.23 ozaki inp = dp->d_inpcb; 1145 1.23 ozaki so = inp->inp_socket; 1146 1.1 rjs 1147 1.1 rjs if (dp->state != DCCPS_ESTAB && extra == 1) { 1148 1.22 andvar /* Only let cc decide when to resend if we are in established state */ 1149 1.1 rjs return 0; 1150 1.1 rjs } 1151 1.1 rjs 1152 1.1 rjs if (so->so_snd.sb_cc){ 1153 1.1 rjs pktlen = dp->pktlen[dp->pktlenidx]; 1154 1.1 rjs } else 1155 1.1 rjs pktlen = 0; 1156 1.1 rjs 1157 1.1 rjs /* Check with CC if we can send... */ 1158 1.1 rjs if (pktlen && dp->cc_in_use[0] > 0 && dp->state == DCCPS_ESTAB) { 1159 1.1 rjs if (!(*cc_sw[dp->cc_in_use[0]].cc_send_packet)(dp->cc_state[0], pktlen)) { 1160 1.1 rjs DCCP_DEBUG((LOG_INFO, "Not allowed to send right now\n")); 1161 1.1 rjs return 0; 1162 1.1 rjs } 1163 1.1 rjs } 1164 1.1 rjs 1165 1.1 rjs if (pktlen) { 1166 1.1 rjs dp->pktcnt --; 1167 1.9 msaitoh dp->pktlenidx = (dp->pktlenidx +1) % DCCP_MAX_PKTS; 1168 1.1 rjs } 1169 1.1 rjs 1170 1.1 rjs again: 1171 1.1 rjs sendalot = 0; 1172 1.1 rjs 1173 1.1 rjs /* 1174 1.1 rjs * off not needed for dccp because we do not need to wait for ACK 1175 1.1 rjs * before removing the packet 1176 1.1 rjs */ 1177 1.1 rjs off = 0; 1178 1.1 rjs optlen = 0; 1179 1.1 rjs 1180 1.1 rjs if (pktlen > dp->d_maxseg) { 1181 1.1 rjs /* this should not happen */ 1182 1.1 rjs DCCP_DEBUG((LOG_INFO, "packet will be fragmented! maxseg %d\n", dp->d_maxseg)); 1183 1.1 rjs len = dp->d_maxseg; 1184 1.1 rjs pktlen -= len; 1185 1.1 rjs sendalot = 1; 1186 1.1 rjs } else 1187 1.1 rjs len = pktlen; 1188 1.1 rjs 1189 1.1 rjs if (extra == DCCP_TYPE_RESET + 2) { 1190 1.1 rjs DCCP_DEBUG((LOG_INFO, "Force sending of DCCP TYPE_RESET! seq=%llu\n", dp->seq_snd)); 1191 1.1 rjs type = DCCP_TYPE_RESET; 1192 1.9 msaitoh extrah_len = 12; 1193 1.1 rjs } else if (dp->state <= DCCPS_REQUEST && dp->who == DCCP_CLIENT) { 1194 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_REQUEST!\n")); 1195 1.1 rjs type = DCCP_TYPE_REQUEST; 1196 1.1 rjs dp->state = DCCPS_REQUEST; 1197 1.9 msaitoh extrah_len = 4; 1198 1.1 rjs } else if (dp->state == DCCPS_REQUEST && dp->who == DCCP_SERVER) { 1199 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_RESPONSE!\n")); 1200 1.1 rjs type = DCCP_TYPE_RESPONSE; 1201 1.1 rjs dp->state = DCCPS_RESPOND; 1202 1.9 msaitoh extrah_len = 12; 1203 1.1 rjs } else if (dp->state == DCCPS_RESPOND) { 1204 1.1 rjs DCCP_DEBUG((LOG_INFO, "Still in feature neg, sending DCCP TYPE_ACK!\n")); 1205 1.1 rjs type = DCCP_TYPE_ACK; 1206 1.1 rjs if (!dp->shortseq) 1207 1.1 rjs extrah_len = 8; 1208 1.1 rjs else { 1209 1.1 rjs extrah_len = 4; 1210 1.1 rjs use_shortseq = 1; 1211 1.1 rjs } 1212 1.1 rjs } else if (dp->state == DCCPS_ESTAB) { 1213 1.1 rjs if (dp->ack_snd && len) { 1214 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_DATAACK!\n")); 1215 1.1 rjs type = DCCP_TYPE_DATAACK; 1216 1.1 rjs /*(u_int32_t *)&extrah = dp->seq_rcv; */ 1217 1.1 rjs if (!dp->shortseq) 1218 1.1 rjs extrah_len = 8; 1219 1.1 rjs else { 1220 1.1 rjs extrah_len = 4; 1221 1.1 rjs use_shortseq = 1; 1222 1.1 rjs } 1223 1.1 rjs } else if (dp->ack_snd) { 1224 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_ACK!\n")); 1225 1.1 rjs type = DCCP_TYPE_ACK; 1226 1.1 rjs if (!dp->shortseq) 1227 1.1 rjs extrah_len = 8; 1228 1.1 rjs else { 1229 1.1 rjs extrah_len = 4; 1230 1.1 rjs use_shortseq = 1; 1231 1.1 rjs } 1232 1.1 rjs } else if (len) { 1233 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_DATA!\n")); 1234 1.1 rjs type = DCCP_TYPE_DATA; 1235 1.1 rjs extrah_len = 0; 1236 1.1 rjs } else { 1237 1.1 rjs DCCP_DEBUG((LOG_INFO, "No ack or data to send!\n")); 1238 1.1 rjs return 0; 1239 1.1 rjs } 1240 1.1 rjs } else if (dp->state == DCCPS_CLIENT_CLOSE) { 1241 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_CLOSE!\n")); 1242 1.1 rjs type = DCCP_TYPE_CLOSE; 1243 1.1 rjs extrah_len = 8; 1244 1.1 rjs } else if (dp->state == DCCPS_SERVER_CLOSE) { 1245 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_CLOSEREQ!\n")); 1246 1.1 rjs type = DCCP_TYPE_CLOSEREQ; 1247 1.1 rjs extrah_len = 8; 1248 1.1 rjs } else { 1249 1.1 rjs DCCP_DEBUG((LOG_INFO, "Hey, we should never get here, state = %u\n", dp->state)); 1250 1.1 rjs return 1; 1251 1.1 rjs } 1252 1.1 rjs 1253 1.1 rjs /* Adding options. */ 1254 1.1 rjs if (dp->optlen) { 1255 1.1 rjs DCCP_DEBUG((LOG_INFO, "Copying options from dp->options! %u\n", dp->optlen)); 1256 1.16 rjs memcpy(options, dp->options, dp->optlen); 1257 1.1 rjs optlen = dp->optlen; 1258 1.1 rjs dp->optlen = 0; 1259 1.1 rjs } 1260 1.1 rjs 1261 1.1 rjs if (dp->featlen && (optlen + dp->featlen < DCCP_MAX_OPTIONS)) { 1262 1.1 rjs DCCP_DEBUG((LOG_INFO, "Copying options from dp->features! %u\n", dp->featlen)); 1263 1.16 rjs memcpy(options + optlen, dp->features, dp->featlen); 1264 1.1 rjs optlen += dp->featlen; 1265 1.1 rjs } 1266 1.1 rjs 1267 1.1 rjs t = optlen % 4; 1268 1.1 rjs 1269 1.1 rjs if (t) { 1270 1.1 rjs t = 4 - t; 1271 1.1 rjs for (i = 0 ; i<t; i++) { 1272 1.1 rjs options[optlen] = 0; 1273 1.1 rjs optlen++; 1274 1.1 rjs } 1275 1.1 rjs } 1276 1.1 rjs 1277 1.1 rjs #ifdef INET6 1278 1.1 rjs if (isipv6) { 1279 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending ipv6 packet...\n")); 1280 1.1 rjs if (!use_shortseq) 1281 1.1 rjs hdrlen = sizeof(struct ip6_hdr) + sizeof(struct dccplhdr) + 1282 1.1 rjs extrah_len + optlen; 1283 1.1 rjs else 1284 1.1 rjs hdrlen = sizeof(struct ip6_hdr) + sizeof(struct dccphdr) + 1285 1.1 rjs extrah_len + optlen; 1286 1.1 rjs } else 1287 1.1 rjs #endif 1288 1.1 rjs { 1289 1.1 rjs if (!use_shortseq) 1290 1.1 rjs hdrlen = sizeof(struct ip) + sizeof(struct dccplhdr) + 1291 1.1 rjs extrah_len + optlen; 1292 1.1 rjs else 1293 1.1 rjs hdrlen = sizeof(struct ip) + sizeof(struct dccphdr) + 1294 1.1 rjs extrah_len + optlen; 1295 1.1 rjs } 1296 1.1 rjs DCCP_DEBUG((LOG_INFO, "Pkt headerlen %u\n", hdrlen)); 1297 1.1 rjs 1298 1.1 rjs if (len > (dp->d_maxseg - extrah_len - optlen)) { 1299 1.1 rjs len = dp->d_maxseg - extrah_len - optlen; 1300 1.1 rjs sendalot = 1; 1301 1.1 rjs } 1302 1.1 rjs 1303 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_HEADER); 1304 1.1 rjs if (m == NULL) { 1305 1.1 rjs error = ENOBUFS; 1306 1.1 rjs goto release; 1307 1.1 rjs } 1308 1.1 rjs if (MHLEN < hdrlen + max_linkhdr) { 1309 1.1 rjs MCLGET(m, M_DONTWAIT); 1310 1.1 rjs if ((m->m_flags & M_EXT) == 0) { 1311 1.1 rjs error = ENOBUFS; 1312 1.1 rjs goto release; 1313 1.1 rjs } 1314 1.1 rjs } 1315 1.1 rjs 1316 1.1 rjs m->m_data += max_linkhdr; 1317 1.1 rjs m->m_len = hdrlen; 1318 1.1 rjs 1319 1.1 rjs if (len) { /* We have data to send */ 1320 1.1 rjs if (len <= M_TRAILINGSPACE(m) - hdrlen) { 1321 1.1 rjs m_copydata(so->so_snd.sb_mb, off, (int) len, 1322 1.1 rjs mtod(m, char *) + hdrlen); 1323 1.1 rjs m->m_len += len; 1324 1.1 rjs } else { 1325 1.18 maxv m->m_next = m_copym(so->so_snd.sb_mb, off, 1326 1.18 maxv (int)len, M_DONTWAIT); 1327 1.1 rjs if (m->m_next == 0) { 1328 1.1 rjs error = ENOBUFS; 1329 1.1 rjs goto release; 1330 1.1 rjs } 1331 1.1 rjs } 1332 1.1 rjs } else { 1333 1.1 rjs dp->ndp++; 1334 1.1 rjs } 1335 1.1 rjs 1336 1.8 ozaki m_reset_rcvif(m); 1337 1.1 rjs 1338 1.1 rjs if (!isipv6 && (len + hdrlen) > IP_MAXPACKET) { 1339 1.1 rjs error = EMSGSIZE; 1340 1.1 rjs goto release; 1341 1.1 rjs } 1342 1.1 rjs 1343 1.1 rjs /* 1344 1.1 rjs * Fill in mbuf with extended DCCP header 1345 1.1 rjs * and addresses and length put into network format. 1346 1.1 rjs */ 1347 1.1 rjs #ifdef INET6 1348 1.1 rjs if (isipv6) { 1349 1.1 rjs ip6 = mtod(m, struct ip6_hdr *); 1350 1.1 rjs dh = (struct dccphdr *)(ip6 + 1); 1351 1.1 rjs ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) | 1352 1.24 ozaki (in6p_flowinfo(inp) & IPV6_FLOWINFO_MASK); 1353 1.1 rjs ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) | 1354 1.1 rjs (IPV6_VERSION & IPV6_VERSION_MASK); 1355 1.1 rjs ip6->ip6_nxt = IPPROTO_DCCP; 1356 1.24 ozaki ip6->ip6_src = in6p_laddr(inp); 1357 1.24 ozaki ip6->ip6_dst = in6p_faddr(inp); 1358 1.1 rjs } else 1359 1.1 rjs #endif 1360 1.1 rjs { 1361 1.1 rjs ip = mtod(m, struct ip *); 1362 1.1 rjs dh = (struct dccphdr *)(ip + 1); 1363 1.16 rjs memset(ip, 0, sizeof(struct ip)); 1364 1.1 rjs ip->ip_p = IPPROTO_DCCP; 1365 1.24 ozaki ip->ip_src = in4p_laddr(inp); 1366 1.24 ozaki ip->ip_dst = in4p_faddr(inp); 1367 1.1 rjs } 1368 1.1 rjs dlh = (struct dccplhdr *)dh; 1369 1.1 rjs 1370 1.23 ozaki dh->dh_sport = inp->inp_lport; 1371 1.23 ozaki dh->dh_dport = inp->inp_fport; 1372 1.1 rjs dh->dh_cscov = dp->cslen; 1373 1.1 rjs dh->dh_ccval = dp->ccval; 1374 1.1 rjs dh->dh_type = type; 1375 1.1 rjs dh->dh_res = 0; /* Reserved field should be zero */ 1376 1.1 rjs if (!use_shortseq) { 1377 1.1 rjs dlh->dh_res2 = 0; /* Reserved field should be zero */ 1378 1.1 rjs dh->dh_off = 4 + (extrah_len / 4) + (optlen / 4); 1379 1.1 rjs } else 1380 1.1 rjs dh->dh_off = 3 + (extrah_len / 4) + (optlen / 4); 1381 1.1 rjs 1382 1.1 rjs dp->seq_snd = (dp->seq_snd +1) % 281474976710656LL; 1383 1.1 rjs if (!use_shortseq) { 1384 1.1 rjs DSEQ_TO_DHDR(dlh, dp->seq_snd); 1385 1.1 rjs dlh->dh_x = 1; 1386 1.1 rjs } else { 1387 1.1 rjs /* short sequene number */ 1388 1.1 rjs dh->dh_seq = htonl(dp->seq_snd) >> 8; 1389 1.1 rjs dh->dh_x = 0; 1390 1.1 rjs } 1391 1.1 rjs 1392 1.1 rjs if (!use_shortseq) { 1393 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending with seq %x.%x, (dp->seq_snd = %llu)\n\n", dlh->dh_seq, dlh->dh_seq2, dp->seq_snd)); 1394 1.1 rjs } else { 1395 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending with seq %x, (dp->seq_snd = %llu)\n\n", dh->dh_seq, dp->seq_snd)); 1396 1.1 rjs } 1397 1.1 rjs 1398 1.1 rjs if (dh->dh_type == DCCP_TYPE_REQUEST) { 1399 1.1 rjs drqh = (struct dccp_requesthdr *)(dlh + 1); 1400 1.1 rjs drqh->drqh_scode = dp->scode; 1401 1.1 rjs optp = (u_char *)(drqh + 1); 1402 1.1 rjs } else if (dh->dh_type == DCCP_TYPE_RESET) { 1403 1.1 rjs drth = (struct dccp_resethdr *)(dlh + 1); 1404 1.1 rjs drth->drth_dash.dah_res = 0; 1405 1.1 rjs DSEQ_TO_DAHDR(drth->drth_dash, dp->seq_rcv); 1406 1.1 rjs if (dp->state == DCCPS_SERVER_CLOSE) 1407 1.9 msaitoh drth->drth_reason = 1; 1408 1.1 rjs else 1409 1.9 msaitoh drth->drth_reason = 2; 1410 1.1 rjs drth->drth_data1 = 0; 1411 1.1 rjs drth->drth_data2 = 0; 1412 1.1 rjs drth->drth_data3 = 0; 1413 1.1 rjs optp = (u_char *)(drth + 1); 1414 1.1 rjs } else if (extrah_len) { 1415 1.1 rjs if (!use_shortseq){ 1416 1.1 rjs dalh = (struct dccp_acklhdr *)(dlh + 1); 1417 1.1 rjs dalh->dash.dah_res = 0; /* Reserved field should be zero */ 1418 1.1 rjs 1419 1.1 rjs if (dp->state == DCCPS_ESTAB) { 1420 1.1 rjs DSEQ_TO_DAHDR(dalh->dash, dp->ack_snd); 1421 1.1 rjs dp->ack_snd = 0; 1422 1.1 rjs } else { 1423 1.1 rjs DSEQ_TO_DAHDR(dalh->dash, dp->seq_rcv); 1424 1.1 rjs } 1425 1.1 rjs 1426 1.1 rjs if (dh->dh_type == DCCP_TYPE_RESPONSE) { 1427 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending dccp type response\n")); 1428 1.1 rjs drqh = (struct dccp_requesthdr *)(dalh + 1); 1429 1.9 msaitoh drqh->drqh_scode = dp->scode; 1430 1.1 rjs optp = (u_char *)(drqh + 1); 1431 1.1 rjs } else 1432 1.1 rjs optp = (u_char *)(dalh + 1); 1433 1.1 rjs } else { 1434 1.1 rjs /* XXX shortseq */ 1435 1.1 rjs dah = (struct dccp_ackhdr *)(dh + 1); 1436 1.1 rjs dah->dash.dah_res = 0; /* Reserved field should be zero */ 1437 1.1 rjs dah->dash.dah_ack = htonl(dp->seq_rcv) >> 8; 1438 1.1 rjs optp = (u_char *)(dah + 1); 1439 1.1 rjs } 1440 1.1 rjs 1441 1.1 rjs } else { 1442 1.1 rjs optp = (u_char *)(dlh + 1); 1443 1.1 rjs } 1444 1.1 rjs 1445 1.1 rjs if (optlen) 1446 1.16 rjs memcpy(optp, options, optlen); 1447 1.1 rjs 1448 1.1 rjs m->m_pkthdr.len = hdrlen + len; 1449 1.1 rjs 1450 1.1 rjs if (dh->dh_cscov == 0) { 1451 1.1 rjs #ifdef INET6 1452 1.1 rjs if (isipv6) 1453 1.1 rjs cslen = (hdrlen - sizeof(struct ip6_hdr)) + len; 1454 1.1 rjs else 1455 1.1 rjs cslen = (hdrlen - sizeof(struct ip)) + len; 1456 1.1 rjs #else 1457 1.1 rjs cslen = (hdrlen - sizeof(struct ip)) + len; 1458 1.1 rjs #endif 1459 1.1 rjs } else { 1460 1.1 rjs cslen = dh->dh_off * 4 + (dh->dh_cscov - 1) * 4; 1461 1.1 rjs #ifdef INET6 1462 1.1 rjs if (isipv6) { 1463 1.1 rjs if (cslen > (hdrlen - sizeof(struct ip6_hdr)) + len) 1464 1.1 rjs cslen = (hdrlen - sizeof(struct ip6_hdr)) + len; 1465 1.1 rjs } else { 1466 1.1 rjs if (cslen > (hdrlen - sizeof(struct ip)) + len) 1467 1.1 rjs cslen = (hdrlen - sizeof(struct ip)) + len; 1468 1.1 rjs } 1469 1.1 rjs #else 1470 1.1 rjs if (cslen > (hdrlen - sizeof(struct ip)) + len) 1471 1.1 rjs cslen = (hdrlen - sizeof(struct ip)) + len; 1472 1.1 rjs #endif 1473 1.1 rjs } 1474 1.1 rjs 1475 1.1 rjs /* 1476 1.1 rjs * Set up checksum 1477 1.1 rjs */ 1478 1.1 rjs m->m_pkthdr.csum_flags = 0; 1479 1.1 rjs 1480 1.1 rjs dh->dh_sum = 0; 1481 1.1 rjs #ifdef INET6 1482 1.1 rjs if (isipv6) { 1483 1.1 rjs dh->dh_sum = in6_cksum(m, IPPROTO_DCCP, sizeof(struct ip6_hdr), 1484 1.1 rjs cslen); 1485 1.1 rjs } else 1486 1.1 rjs #endif 1487 1.1 rjs { 1488 1.1 rjs ip->ip_len = htons(hdrlen + len); 1489 1.1 rjs ip->ip_ttl = dp->inp_ip_ttl; /* XXX */ 1490 1.1 rjs ip->ip_tos = dp->inp_ip_tos; /* XXX */ 1491 1.1 rjs 1492 1.1 rjs dh->dh_sum = in4_cksum(m, IPPROTO_DCCP, sizeof(struct ip), 1493 1.1 rjs cslen); 1494 1.1 rjs #ifndef __OpenBSD__ 1495 1.1 rjs m->m_pkthdr.csum_data = offsetof(struct dccphdr, dh_sum); 1496 1.1 rjs #endif 1497 1.1 rjs } 1498 1.1 rjs 1499 1.1 rjs dccpstat.dccps_opackets++; 1500 1.1 rjs dccpstat.dccps_obytes += m->m_pkthdr.len; 1501 1.1 rjs 1502 1.1 rjs #ifdef INET6 1503 1.1 rjs if (isipv6) { 1504 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling ip_output6, mbuf->m_len = %u, mbuf->m_pkthdr.len = %u\n", m->m_len, m->m_pkthdr.len)); 1505 1.1 rjs 1506 1.24 ozaki error = ip6_output(m, in6p_outputopts(inp), &inp->inp_route, 1507 1.23 ozaki (inp->inp_socket->so_options & SO_DONTROUTE), NULL, NULL, 1508 1.1 rjs NULL); 1509 1.1 rjs } else 1510 1.1 rjs #endif 1511 1.1 rjs { 1512 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling ip_output, mbuf->m_len = %u, mbuf->m_pkthdr.len = %u\n", m->m_len, m->m_pkthdr.len)); 1513 1.1 rjs error = ip_output(m, inp->inp_options, &inp->inp_route, 1514 1.1 rjs (inp->inp_socket->so_options & SO_DONTROUTE), 0, 1515 1.13 ozaki inp); 1516 1.1 rjs } 1517 1.1 rjs 1518 1.1 rjs if (error) { 1519 1.1 rjs DCCP_DEBUG((LOG_INFO, "IP output failed! %d\n", error)); 1520 1.1 rjs return (error); 1521 1.1 rjs } 1522 1.1 rjs 1523 1.23 ozaki sbdrop(&inp->inp_socket->so_snd, len); 1524 1.23 ozaki sowwakeup(inp->inp_socket); 1525 1.1 rjs 1526 1.1 rjs if (dp->cc_in_use[0] > 0 && dp->state == DCCPS_ESTAB) { 1527 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling *cc_sw[%u].cc_send_packet_sent!\n", dp->cc_in_use[0])); 1528 1.1 rjs if (sendalot) { 1529 1.1 rjs (*cc_sw[dp->cc_in_use[0]].cc_send_packet_sent)(dp->cc_state[0], 1,len); 1530 1.1 rjs goto again; 1531 1.1 rjs } else { 1532 1.1 rjs (*cc_sw[dp->cc_in_use[0]].cc_send_packet_sent)(dp->cc_state[0], 0,len); 1533 1.1 rjs } 1534 1.1 rjs } else { 1535 1.1 rjs if (sendalot) 1536 1.1 rjs goto again; 1537 1.1 rjs } 1538 1.1 rjs 1539 1.1 rjs DCCP_DEBUG((LOG_INFO, "dccp_output finished\n")); 1540 1.1 rjs 1541 1.1 rjs return (0); 1542 1.1 rjs 1543 1.1 rjs release: 1544 1.1 rjs m_freem(m); 1545 1.1 rjs return (error); 1546 1.1 rjs } 1547 1.1 rjs 1548 1.1 rjs int 1549 1.1 rjs dccp_abort(struct socket *so) 1550 1.1 rjs { 1551 1.23 ozaki struct inpcb *inp = NULL; 1552 1.1 rjs struct dccpcb *dp; 1553 1.1 rjs 1554 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_abort!\n")); 1555 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 1556 1.23 ozaki inp = sotoinpcb(so); 1557 1.23 ozaki if (inp == NULL) { 1558 1.23 ozaki INP_INFO_WUNLOCK(&dccpbinfo); 1559 1.23 ozaki return EINVAL; 1560 1.1 rjs } 1561 1.23 ozaki dp = inp->inp_ppcb; 1562 1.1 rjs 1563 1.1 rjs dccp_disconnect2(dp); 1564 1.1 rjs 1565 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1566 1.1 rjs return 0; 1567 1.1 rjs } 1568 1.1 rjs 1569 1.1 rjs static struct dccpcb * 1570 1.1 rjs dccp_close(struct dccpcb *dp) 1571 1.1 rjs { 1572 1.1 rjs struct socket *so; 1573 1.1 rjs struct inpcb *inp = dp->d_inpcb; 1574 1.1 rjs so = dptosocket(dp); 1575 1.1 rjs 1576 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_close!\n")); 1577 1.1 rjs 1578 1.1 rjs /* Stop all timers */ 1579 1.1 rjs callout_stop(&dp->connect_timer); 1580 1.1 rjs callout_stop(&dp->retrans_timer); 1581 1.1 rjs callout_stop(&dp->close_timer); 1582 1.1 rjs callout_stop(&dp->timewait_timer); 1583 1.1 rjs 1584 1.1 rjs if (dp->cc_in_use[0] > 0) 1585 1.1 rjs (*cc_sw[dp->cc_in_use[0]].cc_send_free)(dp->cc_state[0]); 1586 1.1 rjs if (dp->cc_in_use[1] > 0) 1587 1.1 rjs (*cc_sw[dp->cc_in_use[1]].cc_recv_free)(dp->cc_state[1]); 1588 1.1 rjs 1589 1.1 rjs pool_put(&dccpcb_pool, dp); 1590 1.23 ozaki inp->inp_ppcb = NULL; 1591 1.23 ozaki soisdisconnected(so); 1592 1.25 ozaki inpcb_destroy(inp); 1593 1.1 rjs return ((struct dccpcb *)0); 1594 1.1 rjs } 1595 1.1 rjs 1596 1.1 rjs /* 1597 1.1 rjs * Runs when a new socket is created with the 1598 1.1 rjs * socket system call or sonewconn. 1599 1.1 rjs */ 1600 1.1 rjs int 1601 1.1 rjs dccp_attach(struct socket *so, int proto) 1602 1.1 rjs { 1603 1.23 ozaki struct inpcb *inp = NULL; 1604 1.1 rjs struct dccpcb *dp; 1605 1.23 ozaki int s, error = 0; 1606 1.1 rjs 1607 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_attach(proto=%d)!\n", proto)); 1608 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 1609 1.1 rjs s = splsoftnet(); 1610 1.1 rjs sosetlock(so); 1611 1.1 rjs 1612 1.23 ozaki inp = sotoinpcb(so); 1613 1.23 ozaki if (inp != 0) { 1614 1.23 ozaki error = EINVAL; 1615 1.1 rjs goto out; 1616 1.1 rjs } 1617 1.23 ozaki error = soreserve(so, dccp_sendspace, dccp_recvspace); 1618 1.23 ozaki if (error) 1619 1.23 ozaki goto out; 1620 1.25 ozaki error = inpcb_create(so, &dccpbtable); 1621 1.23 ozaki if (error) 1622 1.23 ozaki goto out; 1623 1.23 ozaki inp = sotoinpcb(so); 1624 1.1 rjs 1625 1.23 ozaki dp = dccp_newdccpcb(inp->inp_af, inp); 1626 1.1 rjs if (dp == 0) { 1627 1.1 rjs int nofd = so->so_state & SS_NOFDREF; 1628 1.1 rjs so->so_state &= ~SS_NOFDREF; 1629 1.25 ozaki inpcb_destroy(inp); 1630 1.1 rjs so->so_state |= nofd; 1631 1.1 rjs error = ENOBUFS; 1632 1.1 rjs goto out; 1633 1.1 rjs } 1634 1.1 rjs 1635 1.1 rjs #ifdef INET6 1636 1.1 rjs if (proto == PF_INET6) { 1637 1.22 andvar DCCP_DEBUG((LOG_INFO, "We are an ipv6 socket!!!\n")); 1638 1.1 rjs dp->inp_vflag |= INP_IPV6; 1639 1.1 rjs } else 1640 1.1 rjs #endif 1641 1.1 rjs dp->inp_vflag |= INP_IPV4; 1642 1.1 rjs dp->inp_ip_ttl = ip_defttl; 1643 1.1 rjs 1644 1.1 rjs dp->state = DCCPS_CLOSED; 1645 1.1 rjs out: 1646 1.1 rjs splx(s); 1647 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1648 1.1 rjs return error; 1649 1.1 rjs } 1650 1.1 rjs 1651 1.1 rjs static int 1652 1.2 rtr dccp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 1653 1.1 rjs { 1654 1.1 rjs struct inpcb *inp; 1655 1.1 rjs int error; 1656 1.15 rjs int s; 1657 1.2 rtr struct sockaddr_in *sin = (struct sockaddr_in *)nam; 1658 1.1 rjs 1659 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_bind!\n")); 1660 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 1661 1.1 rjs inp = sotoinpcb(so); 1662 1.1 rjs if (inp == 0) { 1663 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1664 1.1 rjs return EINVAL; 1665 1.1 rjs } 1666 1.1 rjs 1667 1.1 rjs /* Do not bind to multicast addresses! */ 1668 1.2 rtr if (sin->sin_family == AF_INET && 1669 1.2 rtr IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 1670 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1671 1.1 rjs return EAFNOSUPPORT; 1672 1.1 rjs } 1673 1.1 rjs INP_LOCK(inp); 1674 1.15 rjs s = splsoftnet(); 1675 1.25 ozaki error = inpcb_bind(inp, sin, l); 1676 1.15 rjs splx(s); 1677 1.1 rjs INP_UNLOCK(inp); 1678 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1679 1.1 rjs return error; 1680 1.1 rjs } 1681 1.1 rjs 1682 1.1 rjs /* 1683 1.1 rjs * Initiates a connection to a server 1684 1.1 rjs * Called by the connect system call. 1685 1.1 rjs */ 1686 1.1 rjs static int 1687 1.6 rtr dccp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 1688 1.1 rjs { 1689 1.1 rjs struct inpcb *inp; 1690 1.1 rjs struct dccpcb *dp; 1691 1.1 rjs int error; 1692 1.1 rjs struct sockaddr_in *sin; 1693 1.1 rjs char test[2]; 1694 1.1 rjs 1695 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_connect!\n")); 1696 1.1 rjs 1697 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 1698 1.1 rjs inp = sotoinpcb(so); 1699 1.1 rjs if (inp == 0) { 1700 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1701 1.1 rjs return EINVAL; 1702 1.1 rjs } 1703 1.1 rjs INP_LOCK(inp); 1704 1.24 ozaki if (in4p_faddr(inp).s_addr != INADDR_ANY) { 1705 1.1 rjs INP_UNLOCK(inp); 1706 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1707 1.1 rjs return EISCONN; 1708 1.1 rjs } 1709 1.1 rjs 1710 1.1 rjs dp = (struct dccpcb *)inp->inp_ppcb; 1711 1.1 rjs 1712 1.1 rjs if (dp->state == DCCPS_ESTAB) { 1713 1.22 andvar DCCP_DEBUG((LOG_INFO, "Why are we in connect when we already have an established connection?\n")); 1714 1.1 rjs } 1715 1.1 rjs 1716 1.1 rjs dp->who = DCCP_CLIENT; 1717 1.1 rjs dp->seq_snd = (((u_int64_t)random() << 32) | random()) % 281474976710656LL; 1718 1.1 rjs dp->ref_seq.hi = dp->seq_snd >> 24; 1719 1.1 rjs dp->ref_seq.lo = (u_int64_t)(dp->seq_snd & 0xffffff); 1720 1.1 rjs DCCP_DEBUG((LOG_INFO, "dccp_connect seq_snd %llu\n", dp->seq_snd)); 1721 1.1 rjs 1722 1.1 rjs dccpstat.dccps_connattempt++; 1723 1.1 rjs 1724 1.1 rjs sin = (struct sockaddr_in *)nam; 1725 1.1 rjs if (sin->sin_family == AF_INET 1726 1.1 rjs && IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 1727 1.1 rjs error = EAFNOSUPPORT; 1728 1.1 rjs goto bad; 1729 1.1 rjs } 1730 1.1 rjs 1731 1.6 rtr error = dccp_doconnect(so, nam, l, 0); 1732 1.1 rjs 1733 1.1 rjs if (error != 0) 1734 1.1 rjs goto bad; 1735 1.1 rjs 1736 1.1 rjs callout_reset(&dp->retrans_timer, dp->retrans, dccp_retrans_t, dp); 1737 1.1 rjs callout_reset(&dp->connect_timer, DCCP_CONNECT_TIMER, dccp_connect_t, dp); 1738 1.1 rjs 1739 1.1 rjs if (dccp_do_feature_nego){ 1740 1.1 rjs test[0] = dp->pref_cc; 1741 1.1 rjs dccp_add_feature(dp, DCCP_OPT_CHANGE_R, DCCP_FEATURE_CC, test, 1); 1742 1.1 rjs } 1743 1.1 rjs 1744 1.1 rjs error = dccp_output(dp, 0); 1745 1.1 rjs 1746 1.1 rjs bad: 1747 1.1 rjs INP_UNLOCK(inp); 1748 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1749 1.1 rjs return error; 1750 1.1 rjs } 1751 1.1 rjs 1752 1.1 rjs static int 1753 1.1 rjs dccp_connect2(struct socket *so, struct socket *so2) 1754 1.1 rjs { 1755 1.1 rjs KASSERT(solocked(so)); 1756 1.1 rjs 1757 1.1 rjs return EOPNOTSUPP; 1758 1.1 rjs } 1759 1.1 rjs 1760 1.1 rjs /* 1761 1.1 rjs * 1762 1.1 rjs * 1763 1.1 rjs */ 1764 1.1 rjs int 1765 1.6 rtr dccp_doconnect(struct socket *so, struct sockaddr *nam, 1766 1.6 rtr struct lwp *l, int isipv6) 1767 1.1 rjs { 1768 1.1 rjs struct inpcb *inp; 1769 1.1 rjs int error = 0; 1770 1.1 rjs 1771 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_doconnect!\n")); 1772 1.1 rjs 1773 1.23 ozaki inp = sotoinpcb(so); 1774 1.1 rjs 1775 1.1 rjs if (inp->inp_lport == 0) { 1776 1.1 rjs #ifdef INET6 1777 1.1 rjs if (isipv6) { 1778 1.26 ozaki DCCP_DEBUG((LOG_INFO, "Running in6pcb_bind!\n")); 1779 1.26 ozaki error = in6pcb_bind(inp, NULL, l); 1780 1.1 rjs } else 1781 1.1 rjs #endif /* INET6 */ 1782 1.1 rjs { 1783 1.25 ozaki error = inpcb_bind(inp, NULL, l); 1784 1.1 rjs } 1785 1.1 rjs if (error) { 1786 1.25 ozaki DCCP_DEBUG((LOG_INFO, "inpcb_bind=%d\n",error)); 1787 1.1 rjs return error; 1788 1.1 rjs } 1789 1.1 rjs } 1790 1.1 rjs 1791 1.1 rjs #ifdef INET6 1792 1.1 rjs if (isipv6) { 1793 1.26 ozaki error = in6pcb_connect(inp, (struct sockaddr_in6 *)nam, l); 1794 1.26 ozaki DCCP_DEBUG((LOG_INFO, "in6pcb_connect=%d\n",error)); 1795 1.1 rjs } else 1796 1.1 rjs #endif 1797 1.25 ozaki error = inpcb_connect(inp, (struct sockaddr_in *)nam, l); 1798 1.1 rjs if (error) { 1799 1.25 ozaki DCCP_DEBUG((LOG_INFO, "inpcb_connect=%d\n",error)); 1800 1.1 rjs return error; 1801 1.1 rjs } 1802 1.1 rjs 1803 1.1 rjs soisconnecting(so); 1804 1.1 rjs return error; 1805 1.1 rjs } 1806 1.1 rjs 1807 1.1 rjs /* 1808 1.1 rjs * Detaches the DCCP protocol from the socket. 1809 1.1 rjs * 1810 1.1 rjs */ 1811 1.1 rjs int 1812 1.1 rjs dccp_detach(struct socket *so) 1813 1.1 rjs { 1814 1.1 rjs struct inpcb *inp; 1815 1.1 rjs struct dccpcb *dp; 1816 1.1 rjs 1817 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_detach!\n")); 1818 1.23 ozaki inp = sotoinpcb(so); 1819 1.23 ozaki if (inp == NULL) { 1820 1.23 ozaki return EINVAL; 1821 1.1 rjs } 1822 1.23 ozaki dp = inp->inp_ppcb; 1823 1.1 rjs if (! dccp_disconnect2(dp)) { 1824 1.1 rjs INP_UNLOCK(inp); 1825 1.1 rjs } 1826 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1827 1.1 rjs return 0; 1828 1.1 rjs } 1829 1.1 rjs 1830 1.1 rjs /* 1831 1.1 rjs * 1832 1.1 rjs * 1833 1.1 rjs */ 1834 1.1 rjs int 1835 1.1 rjs dccp_disconnect(struct socket *so) 1836 1.1 rjs { 1837 1.1 rjs struct inpcb *inp; 1838 1.1 rjs struct dccpcb *dp; 1839 1.1 rjs 1840 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_disconnect!\n")); 1841 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 1842 1.1 rjs #ifndef __NetBSD__ 1843 1.1 rjs inp = sotoinpcb(so); 1844 1.1 rjs if (inp == 0) { 1845 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1846 1.1 rjs return EINVAL; 1847 1.1 rjs } 1848 1.1 rjs INP_LOCK(inp); 1849 1.24 ozaki if (in4p_faddr(inp).s_addr == INADDR_ANY) { 1850 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1851 1.1 rjs INP_UNLOCK(inp); 1852 1.1 rjs return ENOTCONN; 1853 1.1 rjs } 1854 1.1 rjs 1855 1.1 rjs dp = (struct dccpcb *)inp->inp_ppcb; 1856 1.1 rjs #else /* NetBSD */ 1857 1.23 ozaki inp = sotoinpcb(so); 1858 1.23 ozaki if (inp == NULL) { 1859 1.23 ozaki INP_INFO_WUNLOCK(&dccpbinfo); 1860 1.23 ozaki return EINVAL; 1861 1.1 rjs } 1862 1.23 ozaki dp = inp->inp_ppcb; 1863 1.1 rjs #endif 1864 1.1 rjs if (!dccp_disconnect2(dp)) { 1865 1.1 rjs INP_UNLOCK(inp); 1866 1.1 rjs } 1867 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1868 1.1 rjs return 0; 1869 1.1 rjs } 1870 1.1 rjs 1871 1.1 rjs /* 1872 1.22 andvar * If we have don't have an established connection 1873 1.1 rjs * we can call dccp_close, otherwise we can just 1874 1.1 rjs * set SS_ISDISCONNECTED and flush the receive queue. 1875 1.1 rjs */ 1876 1.1 rjs static int 1877 1.1 rjs dccp_disconnect2(struct dccpcb *dp) 1878 1.1 rjs { 1879 1.1 rjs struct socket *so = dptosocket(dp); 1880 1.1 rjs 1881 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_disconnect2!\n")); 1882 1.1 rjs 1883 1.1 rjs if (dp->state < DCCPS_ESTAB) { 1884 1.1 rjs dccp_close(dp); 1885 1.1 rjs return 1; 1886 1.1 rjs } else { 1887 1.1 rjs soisdisconnecting(so); 1888 1.1 rjs sbflush(&so->so_rcv); 1889 1.1 rjs if (dp->state == DCCPS_ESTAB) { 1890 1.1 rjs dp->retrans = 100; 1891 1.1 rjs callout_reset(&dp->retrans_timer, dp->retrans, 1892 1.1 rjs dccp_retrans_t, dp); 1893 1.1 rjs callout_reset(&dp->close_timer, DCCP_CLOSE_TIMER, 1894 1.1 rjs dccp_close_t, dp); 1895 1.1 rjs if (dp->who == DCCP_CLIENT) { 1896 1.1 rjs dp->state = DCCPS_CLIENT_CLOSE; 1897 1.1 rjs } else { 1898 1.1 rjs dp->state = DCCPS_SERVER_CLOSE; 1899 1.1 rjs } 1900 1.1 rjs dccp_output(dp, 0); 1901 1.1 rjs } 1902 1.1 rjs } 1903 1.1 rjs return 0; 1904 1.1 rjs } 1905 1.1 rjs 1906 1.1 rjs int 1907 1.6 rtr dccp_send(struct socket *so, struct mbuf *m, struct sockaddr *addr, 1908 1.1 rjs struct mbuf *control, struct lwp *l) 1909 1.1 rjs { 1910 1.1 rjs struct inpcb *inp; 1911 1.1 rjs struct dccpcb *dp; 1912 1.1 rjs int error = 0; 1913 1.1 rjs int isipv6 = 0; 1914 1.1 rjs 1915 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_send!\n")); 1916 1.1 rjs KASSERT(solocked(so)); 1917 1.1 rjs KASSERT(m != NULL); 1918 1.1 rjs 1919 1.1 rjs if (control && control->m_len) { 1920 1.1 rjs m_freem(control); 1921 1.1 rjs m_freem(m); 1922 1.1 rjs return EINVAL; 1923 1.1 rjs } 1924 1.1 rjs 1925 1.1 rjs #ifdef INET6 1926 1.1 rjs isipv6 = addr && addr->sa_family == AF_INET6; 1927 1.1 rjs #endif 1928 1.1 rjs 1929 1.23 ozaki INP_INFO_WLOCK(&dccpbinfo); 1930 1.23 ozaki inp = sotoinpcb(so); 1931 1.23 ozaki if (inp == NULL) { 1932 1.23 ozaki error = EINVAL; 1933 1.23 ozaki goto release; 1934 1.1 rjs } 1935 1.23 ozaki INP_LOCK(inp); 1936 1.23 ozaki dp = inp->inp_ppcb; 1937 1.23 ozaki 1938 1.1 rjs if (dp->state != DCCPS_ESTAB) { 1939 1.1 rjs DCCP_DEBUG((LOG_INFO, "We have no established connection!\n")); 1940 1.1 rjs } 1941 1.1 rjs 1942 1.1 rjs if (control != NULL) { 1943 1.1 rjs DCCP_DEBUG((LOG_INFO, "We got a control message!\n")); 1944 1.1 rjs /* Are we going to use control messages??? */ 1945 1.1 rjs if (control->m_len) { 1946 1.1 rjs m_freem(control); 1947 1.1 rjs } 1948 1.1 rjs } 1949 1.1 rjs 1950 1.21 christos if (sbspace_oob(&so->so_snd) == 0) { 1951 1.1 rjs INP_UNLOCK(inp); 1952 1.1 rjs error = ENOBUFS; 1953 1.1 rjs goto release; 1954 1.1 rjs } 1955 1.1 rjs 1956 1.1 rjs if (m->m_pkthdr.len > dp->d_maxseg) { 1957 1.1 rjs /* XXX we should calculate packet size more carefully */ 1958 1.1 rjs INP_UNLOCK(inp); 1959 1.1 rjs error = EINVAL; 1960 1.1 rjs goto release; 1961 1.1 rjs } 1962 1.1 rjs 1963 1.1 rjs if (dp->pktcnt >= DCCP_MAX_PKTS) { 1964 1.1 rjs INP_UNLOCK(inp); 1965 1.1 rjs error = ENOBUFS; 1966 1.1 rjs goto release; 1967 1.1 rjs } 1968 1.1 rjs 1969 1.1 rjs sbappend(&so->so_snd, m); 1970 1.9 msaitoh dp->pktlen[(dp->pktlenidx + dp->pktcnt) % DCCP_MAX_PKTS] = m->m_pkthdr.len; 1971 1.1 rjs dp->pktcnt ++; 1972 1.1 rjs 1973 1.1 rjs if (addr && dp->state == DCCPS_CLOSED) { 1974 1.6 rtr error = dccp_doconnect(so, addr, l, isipv6); 1975 1.1 rjs if (error) 1976 1.1 rjs goto out; 1977 1.1 rjs } 1978 1.1 rjs 1979 1.1 rjs error = dccp_output(dp, 0); 1980 1.1 rjs 1981 1.1 rjs out: 1982 1.1 rjs INP_UNLOCK(inp); 1983 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1984 1.9 msaitoh return error; 1985 1.1 rjs 1986 1.1 rjs release: 1987 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 1988 1.1 rjs m_freem(m); 1989 1.1 rjs return (error); 1990 1.1 rjs } 1991 1.1 rjs 1992 1.1 rjs /* 1993 1.1 rjs * Sets socket to SS_CANTSENDMORE 1994 1.1 rjs */ 1995 1.1 rjs int 1996 1.1 rjs dccp_shutdown(struct socket *so) 1997 1.1 rjs { 1998 1.1 rjs struct inpcb *inp; 1999 1.1 rjs 2000 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_shutdown!\n")); 2001 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2002 1.1 rjs inp = sotoinpcb(so); 2003 1.1 rjs if (inp == 0) { 2004 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2005 1.1 rjs return EINVAL; 2006 1.1 rjs } 2007 1.1 rjs INP_LOCK(inp); 2008 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2009 1.1 rjs socantsendmore(so); 2010 1.1 rjs INP_UNLOCK(inp); 2011 1.1 rjs return 0; 2012 1.1 rjs } 2013 1.1 rjs 2014 1.1 rjs static int 2015 1.1 rjs dccp_listen(struct socket *so, struct lwp *td) 2016 1.1 rjs { 2017 1.1 rjs struct inpcb *inp; 2018 1.1 rjs struct dccpcb *dp; 2019 1.1 rjs int error = 0; 2020 1.1 rjs 2021 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_listen!\n")); 2022 1.1 rjs 2023 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2024 1.1 rjs inp = sotoinpcb(so); 2025 1.1 rjs if (inp == 0) { 2026 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2027 1.1 rjs return EINVAL; 2028 1.1 rjs } 2029 1.1 rjs INP_LOCK(inp); 2030 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2031 1.1 rjs dp = (struct dccpcb *)inp->inp_ppcb; 2032 1.1 rjs if (inp->inp_lport == 0) 2033 1.25 ozaki error = inpcb_bind(inp, NULL, td); 2034 1.1 rjs if (error == 0) { 2035 1.1 rjs dp->state = DCCPS_LISTEN; 2036 1.1 rjs dp->who = DCCP_LISTENER; 2037 1.1 rjs } 2038 1.1 rjs INP_UNLOCK(inp); 2039 1.1 rjs return error; 2040 1.1 rjs } 2041 1.1 rjs 2042 1.1 rjs /* 2043 1.1 rjs * Accepts a connection (accept system call) 2044 1.1 rjs */ 2045 1.1 rjs static int 2046 1.3 rtr dccp_accept(struct socket *so, struct sockaddr *nam) 2047 1.1 rjs { 2048 1.1 rjs struct inpcb *inp = NULL; 2049 1.1 rjs int error = 0; 2050 1.1 rjs 2051 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_accept!\n")); 2052 1.1 rjs 2053 1.1 rjs if (nam == NULL) { 2054 1.1 rjs return EINVAL; 2055 1.1 rjs } 2056 1.1 rjs if (so->so_state & SS_ISDISCONNECTED) { 2057 1.1 rjs DCCP_DEBUG((LOG_INFO, "so_state && SS_ISDISCONNECTED!, so->state = %i\n", so->so_state)); 2058 1.1 rjs return ECONNABORTED; 2059 1.1 rjs } 2060 1.1 rjs 2061 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2062 1.1 rjs inp = sotoinpcb(so); 2063 1.1 rjs if (inp == 0) { 2064 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2065 1.1 rjs return EINVAL; 2066 1.1 rjs } 2067 1.1 rjs INP_LOCK(inp); 2068 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2069 1.25 ozaki inpcb_fetch_peeraddr(inp, (struct sockaddr_in *)nam); 2070 1.1 rjs 2071 1.1 rjs return error; 2072 1.1 rjs } 2073 1.1 rjs 2074 1.1 rjs /* 2075 1.1 rjs * Initializes a new DCCP control block 2076 1.25 ozaki * (inpcb_create in attach has already allocated memory for it) 2077 1.1 rjs */ 2078 1.1 rjs struct dccpcb * 2079 1.1 rjs dccp_newdccpcb(int family, void *aux) 2080 1.1 rjs { 2081 1.1 rjs struct inpcb *inp; 2082 1.1 rjs struct dccpcb *dp; 2083 1.1 rjs 2084 1.1 rjs DCCP_DEBUG((LOG_INFO, "Creating a new dccpcb!\n")); 2085 1.1 rjs 2086 1.1 rjs dp = pool_get(&dccpcb_pool, PR_NOWAIT); 2087 1.1 rjs if (dp == NULL) 2088 1.1 rjs return NULL; 2089 1.16 rjs memset((char *) dp, 0, sizeof(struct dccpcb)); 2090 1.1 rjs 2091 1.1 rjs callout_init(&dp->connect_timer, 0); 2092 1.1 rjs callout_init(&dp->retrans_timer, 0); 2093 1.1 rjs callout_init(&dp->close_timer, 0); 2094 1.1 rjs callout_init(&dp->timewait_timer, 0); 2095 1.1 rjs 2096 1.1 rjs dp->ndp = 0; 2097 1.1 rjs dp->loss_window = 1000; 2098 1.1 rjs dp->cslen = 0; 2099 1.1 rjs dp->pref_cc = DEFAULT_CCID; 2100 1.1 rjs dp->who = DCCP_UNDEF; 2101 1.1 rjs dp->seq_snd = 0; 2102 1.1 rjs dp->seq_rcv = 0; 2103 1.1 rjs dp->shortseq = 0; 2104 1.1 rjs dp->gsn_rcv = 281474976710656LL; 2105 1.1 rjs dp->optlen = 0; 2106 1.1 rjs if (dccp_do_feature_nego){ 2107 1.1 rjs dp->cc_in_use[0] = -1; 2108 1.1 rjs dp->cc_in_use[1] = -1; 2109 1.1 rjs } else { 2110 1.1 rjs /* for compatibility with linux */ 2111 1.9 msaitoh dp->cc_in_use[0] = 4; 2112 1.1 rjs dp->cc_in_use[1] = 4; 2113 1.1 rjs } 2114 1.1 rjs dp->av_size = 0; /* no ack vector initially */ 2115 1.1 rjs dp->remote_ackvector = 0; /* no ack vector on remote side initially */ 2116 1.1 rjs dp->retrans = 200; 2117 1.1 rjs dp->avgpsize = 0; 2118 1.1 rjs dp->d_maxseg = 1400; 2119 1.1 rjs dp->ref_pseq.hi = 0; 2120 1.1 rjs dp->ref_pseq.lo = 0; 2121 1.1 rjs dp->pktlenidx = 0; 2122 1.1 rjs dp->pktcnt = 0; 2123 1.1 rjs 2124 1.23 ozaki inp = (struct inpcb *)aux; 2125 1.23 ozaki dp->d_inpcb = inp; 2126 1.23 ozaki inp->inp_ppcb = dp; 2127 1.1 rjs switch (family) { 2128 1.1 rjs case PF_INET: 2129 1.24 ozaki in4p_ip(inp).ip_ttl = ip_defttl; 2130 1.1 rjs break; 2131 1.1 rjs case PF_INET6: 2132 1.26 ozaki in6p_ip6(inp).ip6_hlim = in6pcb_selecthlim_rt(inp); 2133 1.1 rjs break; 2134 1.1 rjs } 2135 1.1 rjs 2136 1.1 rjs if (!dccp_do_feature_nego){ 2137 1.1 rjs dp->cc_state[0] = (*cc_sw[4].cc_send_init)(dp); 2138 1.1 rjs dp->cc_state[1] = (*cc_sw[4].cc_recv_init)(dp); 2139 1.1 rjs } 2140 1.1 rjs 2141 1.1 rjs return dp; 2142 1.1 rjs } 2143 1.1 rjs 2144 1.1 rjs int 2145 1.1 rjs dccp_add_option(struct dccpcb *dp, u_int8_t opt, char *val, u_int8_t val_len) 2146 1.1 rjs { 2147 1.1 rjs return dccp_add_feature_option(dp, opt, 0, val, val_len); 2148 1.1 rjs } 2149 1.1 rjs 2150 1.1 rjs int 2151 1.1 rjs dccp_add_feature_option(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, char *val, u_int8_t val_len) 2152 1.1 rjs { 2153 1.1 rjs int i; 2154 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_add_feature_option, opt = %u, val_len = %u optlen %u\n", opt, val_len, dp->optlen)); 2155 1.1 rjs 2156 1.1 rjs if (DCCP_MAX_OPTIONS > (dp->optlen + val_len + 2)) { 2157 1.1 rjs dp->options[dp->optlen] = opt; 2158 1.1 rjs if (opt < 32) { 2159 1.1 rjs dp->optlen++; 2160 1.1 rjs } else { 2161 1.1 rjs if (opt == DCCP_OPT_CONFIRM_L && val_len) { 2162 1.1 rjs dp->options[dp->optlen + 1] = val_len + 3; 2163 1.1 rjs dp->options[dp->optlen +2] = feature; 2164 1.1 rjs dp->optlen += 3; 2165 1.1 rjs } else { 2166 1.1 rjs dp->options[dp->optlen + 1] = val_len + 2; 2167 1.1 rjs dp->optlen += 2; 2168 1.1 rjs } 2169 1.1 rjs 2170 1.1 rjs for (i = 0; i<val_len; i++) { 2171 1.1 rjs dp->options[dp->optlen] = val[i]; 2172 1.1 rjs dp->optlen++; 2173 1.1 rjs } 2174 1.1 rjs } 2175 1.1 rjs } else { 2176 1.1 rjs DCCP_DEBUG((LOG_INFO, "No room for more options, optlen = %u\n", dp->optlen)); 2177 1.1 rjs return -1; 2178 1.1 rjs } 2179 1.1 rjs 2180 1.1 rjs return 0; 2181 1.1 rjs } 2182 1.1 rjs 2183 1.1 rjs /* 2184 1.1 rjs * Searches "options" for given option type. if found, the data is copied to buffer 2185 1.1 rjs * and returns the data length. 2186 1.1 rjs * Returns 0 if option type not found 2187 1.1 rjs */ 2188 1.1 rjs int 2189 1.1 rjs dccp_get_option(char *options, int optlen, int type, char *buffer, int buflen) 2190 1.1 rjs { 2191 1.1 rjs int i, j, size; 2192 1.1 rjs u_int8_t t; 2193 1.1 rjs 2194 1.1 rjs for (i=0; i < optlen;) { 2195 1.1 rjs t = options[i++]; 2196 1.1 rjs if (t >= 32) { 2197 1.1 rjs size = options[i++] - 2; 2198 1.1 rjs if (t == type) { 2199 1.1 rjs if (size > buflen) 2200 1.1 rjs return 0; 2201 1.1 rjs for (j = 0; j < size; j++) 2202 1.1 rjs buffer[j] = options[i++]; 2203 1.1 rjs return size; 2204 1.1 rjs } 2205 1.1 rjs i += size; 2206 1.1 rjs } 2207 1.1 rjs } 2208 1.1 rjs /* If we get here the options was not found */ 2209 1.1 rjs DCCP_DEBUG((LOG_INFO, "dccp_get_option option(%d) not found\n", type)); 2210 1.1 rjs return 0; 2211 1.1 rjs } 2212 1.1 rjs 2213 1.1 rjs void 2214 1.1 rjs dccp_parse_options(struct dccpcb *dp, char *options, int optlen) 2215 1.1 rjs { 2216 1.1 rjs u_int8_t opt, size, i, j; 2217 1.1 rjs char val[8]; 2218 1.1 rjs 2219 1.1 rjs for (i = 0; i < optlen; i++) { 2220 1.1 rjs opt = options[i]; 2221 1.1 rjs 2222 1.1 rjs DCCP_DEBUG((LOG_INFO, "Parsing opt: 0x%02x\n", opt)); 2223 1.1 rjs 2224 1.1 rjs if (opt < 32) { 2225 1.1 rjs switch (opt) { 2226 1.1 rjs case DCCP_OPT_PADDING: 2227 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_PADDING!\n")); 2228 1.1 rjs break; 2229 1.1 rjs case DCCP_OPT_DATA_DISCARD: 2230 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_DATA_DISCARD!\n")); 2231 1.1 rjs break; 2232 1.1 rjs case DCCP_OPT_SLOW_RECV: 2233 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_SLOW_RECV!\n")); 2234 1.1 rjs break; 2235 1.1 rjs case DCCP_OPT_BUF_CLOSED: 2236 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_BUF_CLOSED!\n")); 2237 1.1 rjs break; 2238 1.1 rjs default: 2239 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got an unknown option, option = %u!\n", opt)); 2240 1.1 rjs } 2241 1.1 rjs } else if (opt > 32 && opt < 36) { 2242 1.1 rjs size = options[i+ 1]; 2243 1.1 rjs if (size < 3 || size > 10) { 2244 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2245 1.1 rjs return; 2246 1.1 rjs } 2247 1.1 rjs /* Feature negotiations are options 33 to 35 */ 2248 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got option %u, size = %u, feature = %u\n", opt, size, options[i+2])); 2249 1.16 rjs memcpy(val, options + i + 3, size -3); 2250 1.1 rjs DCCP_DEBUG((LOG_INFO, "Calling dccp_feature neg(%u, %u, options[%u + 1], %u)!\n", (u_int)dp, opt, i+ 1, (size - 3))); 2251 1.1 rjs dccp_feature_neg(dp, opt, options[i+2], (size -3) , val); 2252 1.1 rjs i += size - 1; 2253 1.1 rjs 2254 1.1 rjs } else if (opt < 128) { 2255 1.1 rjs size = options[i+ 1]; 2256 1.1 rjs if (size < 3 || size > 10) { 2257 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2258 1.1 rjs return; 2259 1.1 rjs } 2260 1.1 rjs 2261 1.1 rjs switch (opt) { 2262 1.1 rjs case DCCP_OPT_RECV_BUF_DROPS: 2263 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_RECV_BUF_DROPS, size = %u!\n", size)); 2264 1.1 rjs for (j=2; j < size; j++) { 2265 1.1 rjs DCCP_DEBUG((LOG_INFO, "val[%u] = %u ", j-1, options[i+j])); 2266 1.1 rjs } 2267 1.1 rjs DCCP_DEBUG((LOG_INFO, "\n")); 2268 1.1 rjs break; 2269 1.1 rjs 2270 1.1 rjs case DCCP_OPT_TIMESTAMP: 2271 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_TIMESTAMP, size = %u\n", size)); 2272 1.1 rjs 2273 1.1 rjs /* Adding TimestampEcho to next outgoing */ 2274 1.16 rjs memcpy(val, options + i + 2, 4); 2275 1.16 rjs memset(val + 4, 0, 4); 2276 1.1 rjs dccp_add_option(dp, DCCP_OPT_TIMESTAMP_ECHO, val, 8); 2277 1.1 rjs break; 2278 1.1 rjs 2279 1.1 rjs case DCCP_OPT_TIMESTAMP_ECHO: 2280 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_TIMESTAMP_ECHO, size = %u\n",size)); 2281 1.1 rjs for (j=2; j < size; j++) { 2282 1.1 rjs DCCP_DEBUG((LOG_INFO, "val[%u] = %u ", j-1, options[i+j])); 2283 1.1 rjs } 2284 1.1 rjs DCCP_DEBUG((LOG_INFO, "\n")); 2285 1.1 rjs 2286 1.1 rjs /* 2287 1.16 rjs memcpy(&(dp->timestamp_echo), options + i + 2, 4); 2288 1.16 rjs memcpy(&(dp->timestamp_elapsed), options + i + 6, 4); 2289 1.16 rjs ACK_DEBUG((LOG_INFO, "DATA; echo = %u , elapsed = %u\n", 2290 1.16 rjs dp->timestamp_echo, dp->timestamp_elapsed)); 2291 1.1 rjs */ 2292 1.1 rjs 2293 1.1 rjs break; 2294 1.1 rjs 2295 1.1 rjs case DCCP_OPT_ACK_VECTOR0: 2296 1.1 rjs case DCCP_OPT_ACK_VECTOR1: 2297 1.1 rjs case DCCP_OPT_ELAPSEDTIME: 2298 1.1 rjs /* Dont do nothing here. Let the CC deal with it */ 2299 1.1 rjs break; 2300 1.1 rjs 2301 1.1 rjs default: 2302 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got an unknown option, option = %u, size = %u!\n", opt, size)); 2303 1.1 rjs break; 2304 1.1 rjs 2305 1.1 rjs } 2306 1.1 rjs i += size - 1; 2307 1.1 rjs 2308 1.1 rjs } else { 2309 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got a CCID option (%d), do nothing!\n", opt)); 2310 1.1 rjs size = options[i+ 1]; 2311 1.1 rjs if (size < 3 || size > 10) { 2312 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2313 1.1 rjs return; 2314 1.1 rjs } 2315 1.1 rjs i += size - 1; 2316 1.1 rjs } 2317 1.1 rjs } 2318 1.1 rjs 2319 1.1 rjs } 2320 1.1 rjs 2321 1.1 rjs int 2322 1.1 rjs dccp_add_feature(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, char *val, u_int8_t val_len) 2323 1.1 rjs { 2324 1.1 rjs int i; 2325 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_add_feature, opt = %u, feature = %u, val_len = %u\n", opt, feature, val_len)); 2326 1.1 rjs 2327 1.1 rjs if (DCCP_MAX_OPTIONS > (dp->featlen + val_len + 3)) { 2328 1.1 rjs dp->features[dp->featlen] = opt; 2329 1.1 rjs dp->features[dp->featlen + 1] = val_len + 3; 2330 1.1 rjs dp->features[dp->featlen +2] = feature; 2331 1.1 rjs dp->featlen += 3; 2332 1.1 rjs for (i = 0; i<val_len; i++) { 2333 1.1 rjs dp->features[dp->featlen] = val[i]; 2334 1.1 rjs dp->featlen++; 2335 1.1 rjs } 2336 1.1 rjs } else { 2337 1.1 rjs DCCP_DEBUG((LOG_INFO, "No room for more features, featlen = %u\n", dp->featlen)); 2338 1.1 rjs return -1; 2339 1.1 rjs } 2340 1.1 rjs 2341 1.1 rjs return 0; 2342 1.1 rjs } 2343 1.1 rjs 2344 1.1 rjs int 2345 1.1 rjs dccp_remove_feature(struct dccpcb *dp, u_int8_t opt, u_int8_t feature) 2346 1.1 rjs { 2347 1.1 rjs int i = 0, j = 0, k; 2348 1.1 rjs u_int8_t t_opt, t_feature, len; 2349 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_remove_feature, featlen = %u, opt = %u, feature = %u\n", dp->featlen, opt, feature)); 2350 1.1 rjs 2351 1.1 rjs while (i < dp->featlen) { 2352 1.1 rjs t_opt = dp->features[i]; 2353 1.1 rjs len = dp->features[i+ 1]; 2354 1.1 rjs 2355 1.1 rjs if (i + len > dp->featlen) { 2356 1.1 rjs DCCP_DEBUG((LOG_INFO, "Error, len = %u and i(%u) + len > dp->featlen (%u)\n", len, i, dp->featlen)); 2357 1.1 rjs return 1; 2358 1.1 rjs } 2359 1.1 rjs t_feature = dp->features[i+2]; 2360 1.1 rjs 2361 1.1 rjs if (t_opt == opt && t_feature == feature) { 2362 1.1 rjs i += len; 2363 1.1 rjs } else { 2364 1.1 rjs if (i != j) { 2365 1.1 rjs for (k = 0; k < len; k++) { 2366 1.1 rjs dp->features[j+k] = dp->features[i+k]; 2367 1.1 rjs } 2368 1.1 rjs } 2369 1.1 rjs i += len; 2370 1.1 rjs j += len; 2371 1.1 rjs } 2372 1.1 rjs } 2373 1.1 rjs dp->featlen = j; 2374 1.1 rjs DCCP_DEBUG((LOG_INFO, "Exiting dccp_remove_feature, featlen = %u\n", dp->featlen)); 2375 1.1 rjs return 0; 2376 1.1 rjs } 2377 1.1 rjs 2378 1.1 rjs void 2379 1.1 rjs dccp_feature_neg(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, u_int8_t val_len, char *val) 2380 1.1 rjs { 2381 1.1 rjs DCCP_DEBUG((LOG_INFO, "Running dccp_feature_neg, opt = %u, feature = %u len = %u ", opt, feature, val_len)); 2382 1.1 rjs 2383 1.1 rjs switch (feature) { 2384 1.1 rjs case DCCP_FEATURE_CC: 2385 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got CCID negotiation, opt = %u, val[0] = %u\n", opt, val[0])); 2386 1.1 rjs if (opt == DCCP_OPT_CHANGE_R) { 2387 1.1 rjs if (val[0] == 2 || val[0] == 3 || val[0] == 0) { 2388 1.1 rjs /* try to use preferable CCID */ 2389 1.1 rjs int i; 2390 1.1 rjs for (i = 1; i < val_len; i ++) if (val[i] == dp->pref_cc) val[0] = dp->pref_cc; 2391 1.1 rjs DCCP_DEBUG((LOG_INFO, "Sending DCCP_OPT_CONFIRM_L on CCID %u\n", val[0])); 2392 1.1 rjs dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_CC); 2393 1.1 rjs dccp_add_feature_option(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_CC , val, 1); 2394 1.1 rjs if (dp->cc_in_use[0] < 1) { 2395 1.1 rjs dp->cc_state[0] = (*cc_sw[val[0] + 1].cc_send_init)(dp); 2396 1.1 rjs dp->cc_in_use[0] = val[0] + 1; 2397 1.1 rjs } else { 2398 1.1 rjs DCCP_DEBUG((LOG_INFO, "We already have negotiated a CC!!!\n")); 2399 1.1 rjs } 2400 1.1 rjs } 2401 1.1 rjs } else if (opt == DCCP_OPT_CONFIRM_L) { 2402 1.1 rjs DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_CONFIRM_L on CCID %u\n", val[0])); 2403 1.1 rjs dccp_remove_feature(dp, DCCP_OPT_CHANGE_R, DCCP_FEATURE_CC); 2404 1.1 rjs if (dp->cc_in_use[1] < 1) { 2405 1.1 rjs dp->cc_state[1] = (*cc_sw[val[0] + 1].cc_recv_init)(dp); 2406 1.1 rjs dp->cc_in_use[1] = val[0] + 1; 2407 1.1 rjs DCCP_DEBUG((LOG_INFO, "confirmed cc_in_use[1] = %d\n", dp->cc_in_use[1])); 2408 1.1 rjs } else { 2409 1.1 rjs DCCP_DEBUG((LOG_INFO, "We already have negotiated a CC!!! (confirm) %d\n", dp->cc_in_use[1])); 2410 1.1 rjs } 2411 1.1 rjs } 2412 1.1 rjs 2413 1.1 rjs break; 2414 1.1 rjs 2415 1.1 rjs case DCCP_FEATURE_ACKVECTOR: 2416 1.1 rjs ACK_DEBUG((LOG_INFO, "Got _Use Ack Vector_\n")); 2417 1.1 rjs if (opt == DCCP_OPT_CHANGE_R) { 2418 1.1 rjs if (val[0] == 1) { 2419 1.1 rjs dccp_use_ackvector(dp); 2420 1.1 rjs dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR); 2421 1.1 rjs dccp_add_feature_option(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR , val, 1); 2422 1.1 rjs } else { 2423 1.1 rjs ACK_DEBUG((LOG_INFO, "ERROR. Strange val %u\n", val[0])); 2424 1.1 rjs } 2425 1.1 rjs } else if (opt == DCCP_OPT_CONFIRM_L) { 2426 1.1 rjs dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR); 2427 1.1 rjs if (val[0] == 1) { 2428 1.1 rjs dp->remote_ackvector = 1; 2429 1.1 rjs ACK_DEBUG((LOG_INFO,"Remote side confirmed AckVector usage\n")); 2430 1.1 rjs } else { 2431 1.1 rjs ACK_DEBUG((LOG_INFO, "ERROR. Strange val %u\n", val[0])); 2432 1.1 rjs } 2433 1.1 rjs } 2434 1.1 rjs break; 2435 1.1 rjs 2436 1.1 rjs case DCCP_FEATURE_ACKRATIO: 2437 1.1 rjs if (opt == DCCP_OPT_CHANGE_R) { 2438 1.16 rjs memcpy(&(dp->ack_ratio), val, 1); 2439 1.1 rjs ACK_DEBUG((LOG_INFO, "Feature: Change Ack Ratio to %u\n", dp->ack_ratio)); 2440 1.1 rjs } 2441 1.1 rjs break; 2442 1.1 rjs 2443 1.1 rjs case DCCP_FEATURE_ECN: 2444 1.1 rjs case DCCP_FEATURE_MOBILITY: 2445 1.1 rjs default: 2446 1.1 rjs /* we should send back empty CONFIRM_L for unknown feature unless it's not mandatory */ 2447 1.1 rjs dccp_add_option(dp, DCCP_OPT_CONFIRM_L, NULL, 0); 2448 1.1 rjs break; 2449 1.1 rjs 2450 1.1 rjs } 2451 1.1 rjs } 2452 1.1 rjs 2453 1.1 rjs #ifdef __FreeBSD__ 2454 1.1 rjs static int 2455 1.1 rjs dccp_pcblist(SYSCTL_HANDLER_ARGS) 2456 1.1 rjs { 2457 1.1 rjs 2458 1.1 rjs int error, i, n, s; 2459 1.1 rjs struct inpcb *inp, **inp_list; 2460 1.1 rjs inp_gen_t gencnt; 2461 1.1 rjs struct xinpgen xig; 2462 1.1 rjs 2463 1.1 rjs /* 2464 1.1 rjs * The process of preparing the TCB list is too time-consuming and 2465 1.1 rjs * resource-intensive to repeat twice on every request. 2466 1.1 rjs */ 2467 1.1 rjs if (req->oldptr == 0) { 2468 1.1 rjs n = dccpbinfo.ipi_count; 2469 1.1 rjs req->oldidx = 2 * (sizeof xig) 2470 1.1 rjs + (n + n/8) * sizeof(struct xdccpcb); 2471 1.1 rjs return 0; 2472 1.1 rjs } 2473 1.1 rjs 2474 1.1 rjs 2475 1.1 rjs if (req->newptr != 0) 2476 1.1 rjs return EPERM; 2477 1.1 rjs 2478 1.1 rjs 2479 1.1 rjs /* 2480 1.1 rjs * OK, now we're committed to doing something. 2481 1.1 rjs */ 2482 1.1 rjs s = splnet(); 2483 1.1 rjs gencnt = dccpbinfo.ipi_gencnt; 2484 1.1 rjs n = dccpbinfo.ipi_count; 2485 1.1 rjs splx(s); 2486 1.1 rjs 2487 1.1 rjs #if __FreeBSD_version >= 500000 2488 1.1 rjs sysctl_wire_old_buffer(req, 2 * (sizeof xig) 2489 1.1 rjs + n * sizeof(struct xdccpcb)); 2490 1.1 rjs #endif 2491 1.1 rjs 2492 1.1 rjs xig.xig_len = sizeof xig; 2493 1.1 rjs xig.xig_count = n; 2494 1.1 rjs xig.xig_gen = gencnt; 2495 1.1 rjs xig.xig_sogen = so_gencnt; 2496 1.1 rjs error = SYSCTL_OUT(req, &xig, sizeof xig); 2497 1.1 rjs if (error) 2498 1.1 rjs return error; 2499 1.1 rjs 2500 1.1 rjs inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); 2501 1.1 rjs if (inp_list == 0) 2502 1.1 rjs return ENOMEM; 2503 1.1 rjs 2504 1.1 rjs s = splsoftnet(); 2505 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2506 1.1 rjs 2507 1.1 rjs for (inp = LIST_FIRST(dccpbinfo.listhead), i = 0; inp && i < n; 2508 1.1 rjs inp = LIST_NEXT(inp, inp_list)) { 2509 1.1 rjs INP_LOCK(inp); 2510 1.1 rjs if (inp->inp_gencnt <= gencnt && 2511 1.1 rjs #if __FreeBSD_version >= 500000 2512 1.1 rjs cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) 2513 1.1 rjs #else 2514 1.1 rjs !prison_xinpcb(req->p, inp)) 2515 1.1 rjs #endif 2516 1.1 rjs inp_list[i++] = inp; 2517 1.1 rjs INP_UNLOCK(inp); 2518 1.1 rjs } 2519 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2520 1.1 rjs splx(s); 2521 1.1 rjs n = i; 2522 1.1 rjs 2523 1.1 rjs error = 0; 2524 1.1 rjs for (i = 0; i < n; i++) { 2525 1.1 rjs inp = inp_list[i]; 2526 1.1 rjs INP_LOCK(inp); 2527 1.1 rjs 2528 1.1 rjs if (inp->inp_gencnt <= gencnt) { 2529 1.1 rjs struct xdccpcb xd; 2530 1.1 rjs vaddr_t inp_ppcb; 2531 1.1 rjs xd.xd_len = sizeof xd; 2532 1.1 rjs /* XXX should avoid extra copy */ 2533 1.16 rjs memcpy(&xd.xd_inp, inp, sizeof *inp); 2534 1.1 rjs inp_ppcb = inp->inp_ppcb; 2535 1.1 rjs if (inp_ppcb != NULL) 2536 1.16 rjs memcpy(&xd.xd_dp, inp_ppcb, sizeof xd.xd_dp); 2537 1.1 rjs else 2538 1.16 rjs memset((char *) &xd.xd_dp, 0, sizeof xd.xd_dp); 2539 1.1 rjs if (inp->inp_socket) 2540 1.1 rjs sotoxsocket(inp->inp_socket, &xd.xd_socket); 2541 1.1 rjs error = SYSCTL_OUT(req, &xd, sizeof xd); 2542 1.1 rjs } 2543 1.1 rjs INP_UNLOCK(inp); 2544 1.1 rjs } 2545 1.1 rjs if (!error) { 2546 1.1 rjs /* 2547 1.1 rjs * Give the user an updated idea of our state. 2548 1.1 rjs * If the generation differs from what we told 2549 1.1 rjs * her before, she knows that something happened 2550 1.1 rjs * while we were processing this request, and it 2551 1.1 rjs * might be necessary to retry. 2552 1.1 rjs */ 2553 1.1 rjs s = splnet(); 2554 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2555 1.1 rjs xig.xig_gen = dccpbinfo.ipi_gencnt; 2556 1.1 rjs xig.xig_sogen = so_gencnt; 2557 1.1 rjs xig.xig_count = dccpbinfo.ipi_count; 2558 1.1 rjs 2559 1.1 rjs 2560 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2561 1.1 rjs splx(s); 2562 1.1 rjs error = SYSCTL_OUT(req, &xig, sizeof xig); 2563 1.1 rjs } 2564 1.1 rjs free(inp_list, M_TEMP); 2565 1.1 rjs return error; 2566 1.1 rjs } 2567 1.1 rjs #endif 2568 1.1 rjs 2569 1.1 rjs #ifdef __FreeBSD__ 2570 1.1 rjs SYSCTL_PROC(_net_inet_dccp, DCCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, 2571 1.1 rjs dccp_pcblist, "S,xdccpcb", "List of active DCCP sockets"); 2572 1.1 rjs #endif 2573 1.1 rjs 2574 1.1 rjs void 2575 1.1 rjs dccp_timewait_t(void *dcb) 2576 1.1 rjs { 2577 1.1 rjs struct dccpcb *dp = dcb; 2578 1.1 rjs 2579 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_timewait_t!\n")); 2580 1.1 rjs mutex_enter(softnet_lock); 2581 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 2582 1.1 rjs INP_LOCK(dp->d_inpcb); 2583 1.1 rjs dccp_close(dp); 2584 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 2585 1.1 rjs mutex_exit(softnet_lock); 2586 1.1 rjs } 2587 1.1 rjs 2588 1.1 rjs void 2589 1.1 rjs dccp_connect_t(void *dcb) 2590 1.1 rjs { 2591 1.1 rjs struct dccpcb *dp = dcb; 2592 1.1 rjs 2593 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_connect_t!\n")); 2594 1.1 rjs mutex_enter(softnet_lock); 2595 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 2596 1.1 rjs INP_LOCK(dp->d_inpcb); 2597 1.1 rjs dccp_close(dp); 2598 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 2599 1.1 rjs mutex_exit(softnet_lock); 2600 1.1 rjs } 2601 1.1 rjs 2602 1.1 rjs void 2603 1.1 rjs dccp_close_t(void *dcb) 2604 1.1 rjs { 2605 1.1 rjs struct dccpcb *dp = dcb; 2606 1.1 rjs 2607 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_close_t!\n")); 2608 1.1 rjs mutex_enter(softnet_lock); 2609 1.1 rjs INP_INFO_WLOCK(&dccpbinfo); 2610 1.1 rjs dp->state = DCCPS_TIME_WAIT; /* HMM */ 2611 1.1 rjs if (dp->who == DCCP_SERVER) { 2612 1.1 rjs INP_LOCK(dp->d_inpcb); 2613 1.1 rjs KERNEL_LOCK(1, NULL); 2614 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 2615 1.1 rjs KERNEL_UNLOCK_ONE(NULL); 2616 1.1 rjs dccp_close(dp); 2617 1.1 rjs } else { 2618 1.1 rjs INP_LOCK(dp->d_inpcb); 2619 1.1 rjs dccp_output(dp, DCCP_TYPE_RESET + 2); 2620 1.1 rjs /*dp->state = DCCPS_TIME_WAIT; */ 2621 1.1 rjs callout_reset(&dp->timewait_timer, DCCP_TIMEWAIT_TIMER, 2622 1.1 rjs dccp_timewait_t, dp); 2623 1.1 rjs INP_UNLOCK(dp->d_inpcb); 2624 1.1 rjs } 2625 1.1 rjs INP_INFO_WUNLOCK(&dccpbinfo); 2626 1.1 rjs mutex_exit(softnet_lock); 2627 1.1 rjs } 2628 1.1 rjs 2629 1.1 rjs void 2630 1.1 rjs dccp_retrans_t(void *dcb) 2631 1.1 rjs { 2632 1.1 rjs struct dccpcb *dp = dcb; 2633 1.1 rjs /*struct inpcb *inp;*/ 2634 1.1 rjs 2635 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_retrans_t!\n")); 2636 1.1 rjs mutex_enter(softnet_lock); 2637 1.1 rjs INP_INFO_RLOCK(&dccpbinfo); 2638 1.1 rjs /*inp = dp->d_inpcb;*/ 2639 1.1 rjs INP_LOCK(inp); 2640 1.1 rjs INP_INFO_RUNLOCK(&dccpbinfo); 2641 1.1 rjs callout_stop(&dp->retrans_timer); 2642 1.1 rjs KERNEL_LOCK(1, NULL); 2643 1.1 rjs dccp_output(dp, 0); 2644 1.1 rjs KERNEL_UNLOCK_ONE(NULL); 2645 1.1 rjs dp->retrans = dp->retrans * 2; 2646 1.1 rjs callout_reset(&dp->retrans_timer, dp->retrans, dccp_retrans_t, dp); 2647 1.1 rjs INP_UNLOCK(inp); 2648 1.1 rjs mutex_exit(softnet_lock); 2649 1.1 rjs } 2650 1.1 rjs 2651 1.1 rjs static int 2652 1.1 rjs dccp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 2653 1.1 rjs { 2654 1.1 rjs int error = 0; 2655 1.1 rjs int family; 2656 1.1 rjs 2657 1.1 rjs family = so->so_proto->pr_domain->dom_family; 2658 1.1 rjs switch (family) { 2659 1.1 rjs case PF_INET: 2660 1.1 rjs error = in_control(so, cmd, nam, ifp); 2661 1.1 rjs break; 2662 1.1 rjs #ifdef INET6 2663 1.1 rjs case PF_INET6: 2664 1.1 rjs error = in6_control(so, cmd, nam, ifp); 2665 1.1 rjs break; 2666 1.1 rjs #endif 2667 1.1 rjs default: 2668 1.1 rjs error = EAFNOSUPPORT; 2669 1.1 rjs } 2670 1.1 rjs return (error); 2671 1.1 rjs } 2672 1.1 rjs 2673 1.1 rjs static int 2674 1.1 rjs dccp_stat(struct socket *so, struct stat *ub) 2675 1.1 rjs { 2676 1.1 rjs return 0; 2677 1.1 rjs } 2678 1.1 rjs 2679 1.1 rjs static int 2680 1.3 rtr dccp_peeraddr(struct socket *so, struct sockaddr *nam) 2681 1.1 rjs { 2682 1.3 rtr 2683 1.1 rjs KASSERT(solocked(so)); 2684 1.1 rjs KASSERT(sotoinpcb(so) != NULL); 2685 1.1 rjs KASSERT(nam != NULL); 2686 1.1 rjs 2687 1.25 ozaki inpcb_fetch_peeraddr(sotoinpcb(so), (struct sockaddr_in *)nam); 2688 1.1 rjs return 0; 2689 1.1 rjs } 2690 1.1 rjs 2691 1.1 rjs static int 2692 1.3 rtr dccp_sockaddr(struct socket *so, struct sockaddr *nam) 2693 1.1 rjs { 2694 1.3 rtr 2695 1.1 rjs KASSERT(solocked(so)); 2696 1.1 rjs KASSERT(sotoinpcb(so) != NULL); 2697 1.1 rjs KASSERT(nam != NULL); 2698 1.1 rjs 2699 1.25 ozaki inpcb_fetch_sockaddr(sotoinpcb(so), (struct sockaddr_in *)nam); 2700 1.1 rjs return 0; 2701 1.1 rjs } 2702 1.1 rjs 2703 1.1 rjs static int 2704 1.1 rjs dccp_rcvd(struct socket *so, int flags, struct lwp *l) 2705 1.1 rjs { 2706 1.1 rjs KASSERT(solocked(so)); 2707 1.1 rjs 2708 1.1 rjs return EOPNOTSUPP; 2709 1.1 rjs } 2710 1.1 rjs 2711 1.1 rjs static int 2712 1.1 rjs dccp_recvoob(struct socket *so, struct mbuf *m, int flags) 2713 1.1 rjs { 2714 1.1 rjs KASSERT(solocked(so)); 2715 1.1 rjs 2716 1.1 rjs return EOPNOTSUPP; 2717 1.1 rjs } 2718 1.1 rjs 2719 1.1 rjs static int 2720 1.1 rjs dccp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 2721 1.1 rjs { 2722 1.1 rjs KASSERT(solocked(so)); 2723 1.1 rjs 2724 1.1 rjs m_freem(m); 2725 1.1 rjs m_freem(control); 2726 1.1 rjs 2727 1.1 rjs return EOPNOTSUPP; 2728 1.1 rjs } 2729 1.1 rjs 2730 1.1 rjs static int 2731 1.1 rjs dccp_purgeif(struct socket *so, struct ifnet *ifp) 2732 1.1 rjs { 2733 1.1 rjs int s; 2734 1.1 rjs 2735 1.1 rjs s = splsoftnet(); 2736 1.1 rjs mutex_enter(softnet_lock); 2737 1.25 ozaki inpcb_purgeif0(&dccpbtable, ifp); 2738 1.1 rjs in_purgeif(ifp); 2739 1.25 ozaki inpcb_purgeif(&dccpbtable, ifp); 2740 1.1 rjs mutex_exit(softnet_lock); 2741 1.1 rjs splx(s); 2742 1.1 rjs 2743 1.1 rjs return 0; 2744 1.1 rjs } 2745 1.1 rjs 2746 1.1 rjs /****** Ack Vector functions *********/ 2747 1.1 rjs 2748 1.1 rjs /** 2749 1.1 rjs * Initialize and allocate mem for Ack Vector 2750 1.1 rjs **/ 2751 1.1 rjs void 2752 1.1 rjs dccp_use_ackvector(struct dccpcb *dp) 2753 1.1 rjs { 2754 1.1 rjs DCCP_DEBUG((LOG_INFO,"Initializing AckVector\n")); 2755 1.1 rjs if (dp->ackvector != 0) { 2756 1.1 rjs DCCP_DEBUG((LOG_INFO, "It was already initialized!!!\n")); 2757 1.1 rjs return; 2758 1.1 rjs } 2759 1.1 rjs dp->av_size = DCCP_VECTORSIZE; 2760 1.1 rjs /* need 2 bits per entry */ 2761 1.1 rjs dp->ackvector = malloc(dp->av_size/4, M_PCB, M_NOWAIT | M_ZERO); 2762 1.1 rjs if (dp->ackvector == 0) { 2763 1.1 rjs DCCP_DEBUG((LOG_INFO, "Unable to allocate memory for ackvector\n")); 2764 1.1 rjs /* What to do now? */ 2765 1.1 rjs dp->av_size = 0; 2766 1.1 rjs return; 2767 1.1 rjs } 2768 1.1 rjs memset(dp->ackvector, 0xff, dp->av_size/4); 2769 1.1 rjs dp->av_hs = dp->av_ts = 0; 2770 1.1 rjs dp->av_hp = dp->ackvector; 2771 1.1 rjs } 2772 1.1 rjs 2773 1.1 rjs /** 2774 1.1 rjs * Set 'seqnr' as the new head in ackvector 2775 1.1 rjs **/ 2776 1.1 rjs void 2777 1.1 rjs dccp_update_ackvector(struct dccpcb *dp, u_int64_t seqnr) 2778 1.1 rjs { 2779 1.1 rjs int64_t gap; 2780 1.1 rjs u_char *t; 2781 1.1 rjs 2782 1.1 rjs /* Ignore wrapping for now */ 2783 1.1 rjs 2784 1.1 rjs ACK_DEBUG((LOG_INFO,"New head in ackvector: %u\n", seqnr)); 2785 1.1 rjs 2786 1.1 rjs if (dp->av_size == 0) { 2787 1.1 rjs ACK_DEBUG((LOG_INFO, "Update: AckVector NOT YET INITIALIZED!!!\n")); 2788 1.1 rjs dccp_use_ackvector(dp); 2789 1.1 rjs } 2790 1.1 rjs 2791 1.1 rjs if (seqnr > dp->av_hs) { 2792 1.1 rjs gap = seqnr - dp->av_hs; 2793 1.1 rjs } else { 2794 1.1 rjs /* We received obsolete information */ 2795 1.1 rjs return; 2796 1.1 rjs } 2797 1.1 rjs 2798 1.1 rjs t = dp->av_hp + (gap/4); 2799 1.1 rjs if (t >= (dp->ackvector + (dp->av_size/4))) 2800 1.1 rjs t -= (dp->av_size / 4); /* ackvector wrapped */ 2801 1.1 rjs dp->av_hp = t; 2802 1.1 rjs dp->av_hs = seqnr; 2803 1.1 rjs } 2804 1.1 rjs 2805 1.1 rjs /** 2806 1.1 rjs * We've received a packet. store in local av so it's included in 2807 1.1 rjs * next Ack Vector sent 2808 1.1 rjs **/ 2809 1.1 rjs void 2810 1.1 rjs dccp_increment_ackvector(struct dccpcb *dp, u_int64_t seqnr) 2811 1.1 rjs { 2812 1.1 rjs u_int64_t offset, dc; 2813 1.1 rjs int64_t gap; 2814 1.1 rjs u_char *t, *n; 2815 1.1 rjs 2816 1.1 rjs DCCP_DEBUG((LOG_INFO, "Entering dccp_increment_ackvecktor %d\n", dp->av_size)); 2817 1.1 rjs if (dp->av_size == 0) { 2818 1.1 rjs DCCP_DEBUG((LOG_INFO, "Increment: AckVector NOT YET INITIALIZED!!!\n")); 2819 1.1 rjs dccp_use_ackvector(dp); 2820 1.1 rjs } 2821 1.1 rjs 2822 1.1 rjs if (dp->av_hs == dp->av_ts) { 2823 1.1 rjs /* Empty ack vector */ 2824 1.1 rjs dp->av_hs = dp->av_ts = seqnr; 2825 1.1 rjs } 2826 1.1 rjs 2827 1.1 rjs /* Check for wrapping */ 2828 1.1 rjs if (seqnr >= dp->av_hs) { 2829 1.1 rjs /* Not wrapped */ 2830 1.1 rjs gap = seqnr - dp->av_hs; 2831 1.1 rjs } else { 2832 1.1 rjs /* Wrapped */ 2833 1.1 rjs gap = seqnr + 0x1000000000000LL - dp->av_hs; /* seqnr = 48 bits */ 2834 1.1 rjs } 2835 1.1 rjs DCCP_DEBUG((LOG_INFO, "dccp_increment_ackvecktor gap=%llu av_size %d\n", gap, dp->av_size)); 2836 1.1 rjs 2837 1.1 rjs if (gap >= dp->av_size) { 2838 1.1 rjs /* gap is bigger than ackvector size? baaad */ 2839 1.1 rjs /* maybe we should increase the ackvector here */ 2840 1.1 rjs DCCP_DEBUG((LOG_INFO, "increment_ackvector error. gap: %llu, av_size: %d, seqnr: %d\n", 2841 1.1 rjs gap, dp->av_size, seqnr)); 2842 1.1 rjs return; 2843 1.1 rjs } 2844 1.1 rjs 2845 1.1 rjs offset = gap % 4; /* hi or low 2 bits to mark */ 2846 1.1 rjs t = dp->av_hp + (gap/4); 2847 1.1 rjs if (t >= (dp->ackvector + (dp->av_size/4))) 2848 1.1 rjs t -= (dp->av_size / 4); /* ackvector wrapped */ 2849 1.1 rjs 2850 1.1 rjs *t = *t & (~(0x03 << (offset *2))); /* turn off bits, 00 is rcvd, 11 is missing */ 2851 1.1 rjs 2852 1.1 rjs dp->av_ts = seqnr + 1; 2853 1.1 rjs if (dp->av_ts == 0x1000000000000LL) 2854 1.1 rjs dp->av_ts = 0; 2855 1.1 rjs 2856 1.1 rjs if (gap > (dp->av_size - 128)) { 2857 1.1 rjs n = malloc(dp->av_size/2, M_PCB, M_NOWAIT | M_ZERO); /* old size * 2 */ 2858 1.1 rjs memset (n + dp->av_size / 4, 0xff, dp->av_size / 4); /* new half all missing */ 2859 1.1 rjs dc = (dp->ackvector + (dp->av_size/4)) - dp->av_hp; 2860 1.1 rjs memcpy (n, dp->av_hp, dc); /* tail to end */ 2861 1.1 rjs memcpy (n+dc, dp->ackvector, dp->av_hp - dp->ackvector); /* start to tail */ 2862 1.1 rjs dp->av_size = dp->av_size * 2; /* counted in items, so it';s a doubling */ 2863 1.1 rjs free (dp->ackvector, M_PCB); 2864 1.1 rjs dp->av_hp = dp->ackvector = n; 2865 1.1 rjs } 2866 1.1 rjs } 2867 1.1 rjs 2868 1.1 rjs /** 2869 1.1 rjs * Generates the ack vector to send in outgoing packet. 2870 1.1 rjs * These are backwards (first packet in ack vector is packet indicated by Ack Number, 2871 1.1 rjs * subsequent are older packets). 2872 1.1 rjs **/ 2873 1.1 rjs 2874 1.1 rjs u_int16_t 2875 1.1 rjs dccp_generate_ackvector(struct dccpcb *dp, u_char *buf) 2876 1.1 rjs { 2877 1.1 rjs int64_t j; 2878 1.1 rjs u_int64_t i; 2879 1.1 rjs u_int16_t cnt, oldlen, bufsize; 2880 1.1 rjs u_char oldstate, st; 2881 1.1 rjs 2882 1.1 rjs bufsize = 16; 2883 1.1 rjs cnt = 0; 2884 1.1 rjs 2885 1.1 rjs oldstate = 0x04; /* bad value */ 2886 1.1 rjs oldlen = 0; 2887 1.1 rjs 2888 1.1 rjs if (dp->av_size == 0) { 2889 1.1 rjs ACK_DEBUG((LOG_INFO, "Generate: AckVector NOT YET INITIALIZED!!!\n")); 2890 1.1 rjs return 0; 2891 1.1 rjs } 2892 1.1 rjs 2893 1.1 rjs if (dp->seq_rcv > dp->av_ts) { 2894 1.1 rjs /* AckNum is beyond our av-list , so we'll start with some 2895 1.1 rjs * 0x3 (Packet not yet received) */ 2896 1.1 rjs j = dp->seq_rcv - dp->av_ts -1; 2897 1.1 rjs do { 2898 1.1 rjs /* state | length */ 2899 1.1 rjs oldstate = 0x03; 2900 1.1 rjs if (j > 63) 2901 1.1 rjs oldlen = 63; 2902 1.1 rjs else 2903 1.1 rjs oldlen = j; 2904 1.1 rjs 2905 1.1 rjs buf[cnt] = (0x03 << 6) | oldlen; 2906 1.1 rjs cnt++; 2907 1.1 rjs if (cnt == bufsize) { 2908 1.1 rjs /* I've skipped the realloc bshit */ 2909 1.1 rjs /* PANIC */ 2910 1.1 rjs } 2911 1.1 rjs j-=63; 2912 1.1 rjs } while (j > 0); 2913 1.1 rjs } 2914 1.1 rjs 2915 1.1 rjs /* Ok now we're at dp->av_ts (unless AckNum is lower) */ 2916 1.1 rjs i = (dp->seq_rcv < dp->av_ts) ? dp->seq_rcv : dp->av_ts; 2917 1.1 rjs st = dccp_ackvector_state(dp, i); 2918 1.1 rjs 2919 1.1 rjs if (st == oldstate) { 2920 1.1 rjs cnt--; 2921 1.1 rjs oldlen++; 2922 1.1 rjs } else { 2923 1.1 rjs oldlen = 0; 2924 1.1 rjs oldstate = st; 2925 1.1 rjs } 2926 1.1 rjs 2927 1.1 rjs if (dp->av_ts > dp->av_hs) { 2928 1.1 rjs do { 2929 1.1 rjs i--; 2930 1.1 rjs st = dccp_ackvector_state(dp, i); 2931 1.1 rjs if (st == oldstate && oldlen < 64) { 2932 1.1 rjs oldlen++; 2933 1.1 rjs } else { 2934 1.1 rjs buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2935 1.1 rjs cnt++; 2936 1.1 rjs oldlen = 0; 2937 1.1 rjs oldstate = st; 2938 1.1 rjs if (cnt == bufsize) { 2939 1.1 rjs /* PANIC */ 2940 1.1 rjs } 2941 1.1 rjs } 2942 1.1 rjs 2943 1.1 rjs } while (i > dp->av_hs); 2944 1.1 rjs } else { 2945 1.1 rjs /* It's wrapped */ 2946 1.1 rjs do { 2947 1.1 rjs i--; 2948 1.1 rjs st = dccp_ackvector_state(dp, i); 2949 1.1 rjs if (st == oldstate && oldlen < 64) { 2950 1.1 rjs oldlen++; 2951 1.1 rjs } else { 2952 1.1 rjs buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2953 1.1 rjs cnt++; 2954 1.1 rjs oldlen = 0; 2955 1.1 rjs oldstate = st; 2956 1.1 rjs if (cnt == bufsize) { 2957 1.1 rjs /* PANIC */ 2958 1.1 rjs } 2959 1.1 rjs } 2960 1.1 rjs 2961 1.1 rjs } while (i > 0); 2962 1.1 rjs i = 0x1000000; 2963 1.1 rjs do { 2964 1.1 rjs i--; 2965 1.1 rjs st = dccp_ackvector_state(dp, i); 2966 1.1 rjs if (st == oldstate && oldlen < 64) { 2967 1.1 rjs oldlen++; 2968 1.1 rjs } else { 2969 1.1 rjs buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2970 1.1 rjs cnt++; 2971 1.1 rjs oldlen = 0; 2972 1.1 rjs oldstate = st; 2973 1.1 rjs if (cnt == bufsize) { 2974 1.1 rjs /* PANIC */ 2975 1.1 rjs } 2976 1.1 rjs } 2977 1.1 rjs } while (i > dp->av_hs); 2978 1.1 rjs } 2979 1.1 rjs 2980 1.1 rjs /* add the last one */ 2981 1.1 rjs buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2982 1.1 rjs cnt++; 2983 1.1 rjs 2984 1.1 rjs return cnt; 2985 1.1 rjs } 2986 1.1 rjs 2987 1.1 rjs u_char 2988 1.1 rjs dccp_ackvector_state(struct dccpcb *dp, u_int64_t seqnr) 2989 1.1 rjs { 2990 1.1 rjs u_int64_t gap, offset; 2991 1.1 rjs u_char *t; 2992 1.1 rjs 2993 1.1 rjs /* Check for wrapping */ 2994 1.1 rjs if (seqnr >= dp->av_hs) { 2995 1.1 rjs /* Not wrapped */ 2996 1.1 rjs gap = seqnr - dp->av_hs; 2997 1.1 rjs } else { 2998 1.1 rjs /* Wrapped */ 2999 1.1 rjs gap = seqnr + 0x1000000000000LL - dp->av_hs; /* seq nr = 48 bits */ 3000 1.1 rjs } 3001 1.1 rjs 3002 1.1 rjs if (gap >= dp->av_size) { 3003 1.1 rjs /* gap is bigger than ackvector size? baaad */ 3004 1.1 rjs return 0x03; 3005 1.1 rjs } 3006 1.1 rjs 3007 1.1 rjs offset = gap % 4 *2; 3008 1.1 rjs t = dp->av_hp + (gap/4); 3009 1.1 rjs if (t >= (dp->ackvector + (dp->av_size/4))) 3010 1.1 rjs t -= (dp->av_size / 4); /* wrapped */ 3011 1.1 rjs 3012 1.1 rjs return ((*t & (0x03 << offset)) >> offset); 3013 1.1 rjs } 3014 1.1 rjs 3015 1.1 rjs /****** End of Ack Vector functions *********/ 3016 1.1 rjs 3017 1.1 rjs /* No cc functions */ 3018 1.1 rjs void * 3019 1.1 rjs dccp_nocc_init(struct dccpcb *pcb) 3020 1.1 rjs { 3021 1.1 rjs return (void*) 1; 3022 1.1 rjs } 3023 1.1 rjs 3024 1.1 rjs void 3025 1.1 rjs dccp_nocc_free(void *ccb) 3026 1.1 rjs { 3027 1.1 rjs } 3028 1.1 rjs 3029 1.1 rjs int 3030 1.1 rjs dccp_nocc_send_packet(void *ccb, long size) 3031 1.1 rjs { 3032 1.1 rjs return 1; 3033 1.1 rjs } 3034 1.1 rjs 3035 1.1 rjs void 3036 1.1 rjs dccp_nocc_send_packet_sent(void *ccb, int moreToSend, long size) 3037 1.1 rjs { 3038 1.1 rjs } 3039 1.1 rjs 3040 1.1 rjs void 3041 1.1 rjs dccp_nocc_packet_recv(void *ccb, char* options ,int optlen) 3042 1.1 rjs { 3043 1.1 rjs } 3044 1.1 rjs 3045 1.1 rjs void 3046 1.1 rjs dccp_log(int level, const char *format, ...) 3047 1.1 rjs { 3048 1.1 rjs va_list ap; 3049 1.1 rjs 3050 1.1 rjs va_start(ap, format); 3051 1.1 rjs vprintf(format, ap); 3052 1.1 rjs va_end(ap); 3053 1.1 rjs return; 3054 1.1 rjs } 3055 1.1 rjs 3056 1.1 rjs /* 3057 1.1 rjs * Sysctl for dccp variables. 3058 1.1 rjs */ 3059 1.1 rjs SYSCTL_SETUP(sysctl_net_inet_dccp_setup, "sysctl net.inet.dccp subtree setup") 3060 1.1 rjs { 3061 1.1 rjs 3062 1.1 rjs sysctl_createv(clog, 0, NULL, NULL, 3063 1.1 rjs CTLFLAG_PERMANENT, 3064 1.1 rjs CTLTYPE_NODE, "net", NULL, 3065 1.1 rjs NULL, 0, NULL, 0, 3066 1.1 rjs CTL_NET, CTL_EOL); 3067 1.1 rjs 3068 1.1 rjs sysctl_createv(clog, 0, NULL, NULL, 3069 1.1 rjs CTLFLAG_PERMANENT, 3070 1.1 rjs CTLTYPE_NODE, "inet", NULL, 3071 1.1 rjs NULL, 0, NULL, 0, 3072 1.1 rjs CTL_NET, PF_INET, CTL_EOL); 3073 1.1 rjs 3074 1.1 rjs sysctl_createv(clog, 0, NULL, NULL, 3075 1.1 rjs CTLFLAG_PERMANENT, 3076 1.1 rjs CTLTYPE_NODE, "dccp", 3077 1.1 rjs SYSCTL_DESCR("DCCPv4 related settings"), 3078 1.1 rjs NULL, 0, NULL, 0, 3079 1.1 rjs CTL_NET, PF_INET, IPPROTO_DCCP, CTL_EOL); 3080 1.1 rjs 3081 1.1 rjs sysctl_createv(clog, 0, NULL, NULL, 3082 1.1 rjs CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3083 1.1 rjs CTLTYPE_INT, "dccp_log_in_vain", 3084 1.1 rjs SYSCTL_DESCR("log all connection attempt"), 3085 1.1 rjs NULL, 0, &dccp_log_in_vain, 0, 3086 1.1 rjs CTL_NET, PF_INET, IPPROTO_DCCP, DCCPCTL_LOGINVAIN, 3087 1.1 rjs CTL_EOL); 3088 1.1 rjs 3089 1.1 rjs sysctl_createv(clog, 0, NULL, NULL, 3090 1.1 rjs CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3091 1.1 rjs CTLTYPE_INT, "do_feature_nego", 3092 1.1 rjs SYSCTL_DESCR("enable feature negotiation"), 3093 1.1 rjs NULL, 0, &dccp_do_feature_nego, 0, 3094 1.1 rjs CTL_NET, PF_INET, IPPROTO_DCCP, DCCPCTL_DOFEATURENEGO, 3095 1.1 rjs CTL_EOL); 3096 1.1 rjs } 3097 1.1 rjs 3098 1.1 rjs PR_WRAP_USRREQS(dccp) 3099 1.1 rjs #define dccp_attach dccp_attach_wrapper 3100 1.1 rjs #define dccp_detach dccp_detach_wrapper 3101 1.1 rjs #define dccp_accept dccp_accept_wrapper 3102 1.1 rjs #define dccp_bind dccp_bind_wrapper 3103 1.1 rjs #define dccp_listen dccp_listen_wrapper 3104 1.1 rjs #define dccp_connect dccp_connect_wrapper 3105 1.1 rjs #define dccp_connect2 dccp_connect2_wrapper 3106 1.1 rjs #define dccp_disconnect dccp_disconnect_wrapper 3107 1.1 rjs #define dccp_shutdown dccp_shutdown_wrapper 3108 1.1 rjs #define dccp_abort dccp_abort_wrapper 3109 1.1 rjs #define dccp_ioctl dccp_ioctl_wrapper 3110 1.1 rjs #define dccp_stat dccp_stat_wrapper 3111 1.1 rjs #define dccp_peeraddr dccp_peeraddr_wrapper 3112 1.1 rjs #define dccp_sockaddr dccp_sockaddr_wrapper 3113 1.1 rjs #define dccp_rcvd dccp_rcvd_wrapper 3114 1.1 rjs #define dccp_recvoob dccp_recvoob_wrapper 3115 1.1 rjs #define dccp_send dccp_send_wrapper 3116 1.1 rjs #define dccp_sendoob dccp_sendoob_wrapper 3117 1.1 rjs #define dccp_purgeif dccp_purgeif_wrapper 3118 1.1 rjs 3119 1.1 rjs const struct pr_usrreqs dccp_usrreqs = { 3120 1.1 rjs .pr_attach = dccp_attach, 3121 1.1 rjs .pr_detach = dccp_detach, 3122 1.1 rjs .pr_accept = dccp_accept, 3123 1.1 rjs .pr_bind = dccp_bind, 3124 1.1 rjs .pr_listen = dccp_listen, 3125 1.1 rjs .pr_connect = dccp_connect, 3126 1.1 rjs .pr_connect2 = dccp_connect2, 3127 1.1 rjs .pr_disconnect = dccp_disconnect, 3128 1.1 rjs .pr_shutdown = dccp_shutdown, 3129 1.1 rjs .pr_abort = dccp_abort, 3130 1.1 rjs .pr_ioctl = dccp_ioctl, 3131 1.1 rjs .pr_stat = dccp_stat, 3132 1.1 rjs .pr_peeraddr = dccp_peeraddr, 3133 1.1 rjs .pr_sockaddr = dccp_sockaddr, 3134 1.1 rjs .pr_rcvd = dccp_rcvd, 3135 1.1 rjs .pr_recvoob = dccp_recvoob, 3136 1.1 rjs .pr_send = dccp_send, 3137 1.1 rjs .pr_sendoob = dccp_sendoob, 3138 1.1 rjs .pr_purgeif = dccp_purgeif, 3139 1.1 rjs }; 3140