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