1 /* $KAME: dccp_usrreq.c,v 1.67 2005/11/03 16:05:04 nishida Exp $ */ 2 /* $NetBSD: dccp_usrreq.c,v 1.27 2024/07/05 04:31:54 rin 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.27 2024/07/05 04:31:54 rin 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 DCCP_DEBUG((LOG_INFO, "state & SS_CANTRCVMORE...!\n")); 885 m_freem(m); 886 m_freem(opts); 887 } else { 888 m_adj(m, (iphlen + data_off)); 889 DCCP_DEBUG((LOG_INFO, "Calling sbappend!\n")); 890 sbappend(&so->so_rcv, m); 891 } 892 DCCP_DEBUG((LOG_INFO, "Calling sorwakeup...!\n")); 893 sorwakeup(so); 894 } else { 895 m_freem(m); 896 m_freem(opts); 897 } 898 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 899 if (dp) 900 INP_UNLOCK(inp); 901 #endif 902 903 return; 904 905 badunlocked: 906 m_freem(m); 907 m_freem(opts); 908 return; 909 } 910 911 /* 912 * Notify a dccp user of an asynchronous error; 913 * just wake up so that he can collect error status. 914 */ 915 void 916 dccp_notify(struct inpcb *inp, int errno) 917 { 918 inp->inp_socket->so_error = errno; 919 sorwakeup(inp->inp_socket); 920 sowwakeup(inp->inp_socket); 921 return; 922 } 923 924 /* 925 * Called when we get ICMP errors (destination unreachable, 926 * parameter problem, source quench, time exceeded and redirects) 927 */ 928 void * 929 dccp_ctlinput(int cmd, const struct sockaddr *sa, void *vip) 930 { 931 struct ip *ip = vip; 932 struct dccphdr *dh; 933 void (*notify)(struct inpcb *, int) = dccp_notify; 934 struct in_addr faddr; 935 struct inpcb *inp = NULL; 936 937 faddr = ((const struct sockaddr_in *)sa)->sin_addr; 938 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) 939 return NULL; 940 941 if (PRC_IS_REDIRECT(cmd)) { 942 ip = 0; 943 notify = inpcb_rtchange; 944 } else if (cmd == PRC_HOSTDEAD) 945 ip = 0; 946 else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) 947 return NULL; 948 if (ip) { 949 /*s = splsoftnet();*/ 950 dh = (struct dccphdr *)((vaddr_t)ip + (ip->ip_hl << 2)); 951 INP_INFO_RLOCK(&dccpbinfo); 952 inpcb_notify(&dccpbtable, faddr, dh->dh_dport, 953 ip->ip_src, dh->dh_sport, inetctlerrmap[cmd], notify); 954 if (inp != NULL) { 955 INP_LOCK(inp); 956 if (inp->inp_socket != NULL) { 957 (*notify)(inp, inetctlerrmap[cmd]); 958 } 959 INP_UNLOCK(inp); 960 } 961 INP_INFO_RUNLOCK(&dccpbinfo); 962 /*splx(s);*/ 963 } else 964 inpcb_notifyall(&dccpbtable, faddr, inetctlerrmap[cmd], notify); 965 966 return NULL; 967 } 968 969 static int 970 dccp_optsset(struct dccpcb *dp, struct sockopt *sopt) 971 { 972 int optval; 973 int error = 0; 974 975 switch (sopt->sopt_name) { 976 case DCCP_CCID: 977 error = sockopt_getint(sopt, &optval); 978 /* Add check that optval is a CCID we support!!! */ 979 if (optval == 2 || optval == 3 || optval == 0) { 980 dp->pref_cc = optval; 981 } else { 982 error = EINVAL; 983 } 984 break; 985 case DCCP_CSLEN: 986 error = sockopt_getint(sopt, &optval); 987 if (optval > 15 || optval < 0) { 988 error = EINVAL; 989 } else { 990 dp->cslen = optval; 991 } 992 break; 993 case DCCP_MAXSEG: 994 error = sockopt_getint(sopt, &optval); 995 if (optval > 0 && optval <= dp->d_maxseg) { 996 dp->d_maxseg = optval; 997 } else { 998 error = EINVAL; 999 } 1000 break; 1001 case DCCP_SERVICE: 1002 error = sockopt_getint(sopt, &optval); 1003 dp->scode = optval; 1004 break; 1005 1006 default: 1007 error = ENOPROTOOPT; 1008 } 1009 1010 return error; 1011 } 1012 1013 static int 1014 dccp_optsget(struct dccpcb *dp, struct sockopt *sopt) 1015 { 1016 int optval = 0; 1017 int error = 0; 1018 1019 switch (sopt->sopt_name) { 1020 case DCCP_CCID: 1021 optval = dp->pref_cc; 1022 error = sockopt_set(sopt, &optval, sizeof(optval)); 1023 break; 1024 case DCCP_CSLEN: 1025 optval = dp->cslen; 1026 error = sockopt_set(sopt, &optval, sizeof(optval)); 1027 break; 1028 case DCCP_MAXSEG: 1029 optval = dp->d_maxseg; 1030 error = sockopt_set(sopt, &optval, sizeof(optval)); 1031 break; 1032 case DCCP_SERVICE: 1033 optval = dp->scode; 1034 error = sockopt_set(sopt, &optval, sizeof(optval)); 1035 break; 1036 default: 1037 error = ENOPROTOOPT; 1038 } 1039 1040 return error; 1041 } 1042 1043 /* 1044 * Called by getsockopt and setsockopt. 1045 * 1046 */ 1047 int 1048 dccp_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1049 { 1050 int s, error = 0; 1051 struct inpcb *inp; 1052 struct dccpcb *dp; 1053 int family; /* family of the socket */ 1054 1055 family = so->so_proto->pr_domain->dom_family; 1056 error = 0; 1057 1058 s = splsoftnet(); 1059 INP_INFO_RLOCK(&dccpbinfo); 1060 inp = sotoinpcb(so); 1061 if (inp == NULL) 1062 { 1063 INP_INFO_RUNLOCK(&dccpbinfo); 1064 splx(s); 1065 return (ECONNRESET); 1066 } 1067 /* 1068 if (inp) 1069 INP_LOCK(inp); 1070 else 1071 IN6P_LOCK(in6p); 1072 INP_INFO_RUNLOCK(&dccpbinfo); 1073 */ 1074 if (sopt->sopt_level != IPPROTO_DCCP) { 1075 switch (family) { 1076 case PF_INET: 1077 error = ip_ctloutput(op, so, sopt); 1078 break; 1079 #if defined(INET6) 1080 case PF_INET6: 1081 error = ip6_ctloutput(op, so, sopt); 1082 break; 1083 #endif 1084 } 1085 splx(s); 1086 return (error); 1087 } 1088 1089 dp = intodccpcb(inp); 1090 1091 if (op == PRCO_SETOPT) { 1092 error = dccp_optsset(dp, sopt); 1093 } else if (op == PRCO_GETOPT) { 1094 error = dccp_optsget(dp, sopt); 1095 } else { 1096 error = EINVAL; 1097 } 1098 /* 1099 if (inp) 1100 INP_UNLOCK(inp); 1101 else 1102 IN6P_UNLOCK(in6p); 1103 */ 1104 splx(s); 1105 return error; 1106 } 1107 1108 int 1109 dccp_output(struct dccpcb *dp, u_int8_t extra) 1110 { 1111 struct inpcb *inp; 1112 struct socket *so; 1113 struct mbuf *m; 1114 1115 struct ip *ip = NULL; 1116 struct dccphdr *dh; 1117 struct dccplhdr *dlh; 1118 struct dccp_requesthdr *drqh; 1119 struct dccp_ackhdr *dah; 1120 struct dccp_acklhdr *dalh; 1121 struct dccp_resethdr *drth; 1122 u_char *optp = NULL; 1123 int error = 0; 1124 int off, sendalot, t, i; 1125 u_int32_t hdrlen, optlen, extrah_len, cslen; 1126 u_int8_t type; 1127 char options[DCCP_MAX_OPTIONS *2]; 1128 long len, pktlen; 1129 int isipv6 = 0; 1130 int use_shortseq = 0; 1131 #ifdef INET6 1132 struct ip6_hdr *ip6 = NULL; 1133 #endif 1134 1135 DCCP_DEBUG((LOG_INFO, "dccp_output start!\n")); 1136 1137 isipv6 = (dp->inp_vflag & INP_IPV6) != 0; 1138 1139 DCCP_DEBUG((LOG_INFO, "Going to send a DCCP packet!\n")); 1140 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 1141 KASSERT(mutex_assert(&dp->d_inpcb->inp_mtx, MA_OWNED)); 1142 #endif 1143 1144 inp = dp->d_inpcb; 1145 so = inp->inp_socket; 1146 1147 if (dp->state != DCCPS_ESTAB && extra == 1) { 1148 /* Only let cc decide when to resend if we are in established state */ 1149 return 0; 1150 } 1151 1152 if (so->so_snd.sb_cc){ 1153 pktlen = dp->pktlen[dp->pktlenidx]; 1154 } else 1155 pktlen = 0; 1156 1157 /* Check with CC if we can send... */ 1158 if (pktlen && dp->cc_in_use[0] > 0 && dp->state == DCCPS_ESTAB) { 1159 if (!(*cc_sw[dp->cc_in_use[0]].cc_send_packet)(dp->cc_state[0], pktlen)) { 1160 DCCP_DEBUG((LOG_INFO, "Not allowed to send right now\n")); 1161 return 0; 1162 } 1163 } 1164 1165 if (pktlen) { 1166 dp->pktcnt --; 1167 dp->pktlenidx = (dp->pktlenidx +1) % DCCP_MAX_PKTS; 1168 } 1169 1170 again: 1171 sendalot = 0; 1172 1173 /* 1174 * off not needed for dccp because we do not need to wait for ACK 1175 * before removing the packet 1176 */ 1177 off = 0; 1178 optlen = 0; 1179 1180 if (pktlen > dp->d_maxseg) { 1181 /* this should not happen */ 1182 DCCP_DEBUG((LOG_INFO, "packet will be fragmented! maxseg %d\n", dp->d_maxseg)); 1183 len = dp->d_maxseg; 1184 pktlen -= len; 1185 sendalot = 1; 1186 } else 1187 len = pktlen; 1188 1189 if (extra == DCCP_TYPE_RESET + 2) { 1190 DCCP_DEBUG((LOG_INFO, "Force sending of DCCP TYPE_RESET! seq=%llu\n", dp->seq_snd)); 1191 type = DCCP_TYPE_RESET; 1192 extrah_len = 12; 1193 } else if (dp->state <= DCCPS_REQUEST && dp->who == DCCP_CLIENT) { 1194 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_REQUEST!\n")); 1195 type = DCCP_TYPE_REQUEST; 1196 dp->state = DCCPS_REQUEST; 1197 extrah_len = 4; 1198 } else if (dp->state == DCCPS_REQUEST && dp->who == DCCP_SERVER) { 1199 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_RESPONSE!\n")); 1200 type = DCCP_TYPE_RESPONSE; 1201 dp->state = DCCPS_RESPOND; 1202 extrah_len = 12; 1203 } else if (dp->state == DCCPS_RESPOND) { 1204 DCCP_DEBUG((LOG_INFO, "Still in feature neg, sending DCCP TYPE_ACK!\n")); 1205 type = DCCP_TYPE_ACK; 1206 if (!dp->shortseq) 1207 extrah_len = 8; 1208 else { 1209 extrah_len = 4; 1210 use_shortseq = 1; 1211 } 1212 } else if (dp->state == DCCPS_ESTAB) { 1213 if (dp->ack_snd && len) { 1214 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_DATAACK!\n")); 1215 type = DCCP_TYPE_DATAACK; 1216 /*(u_int32_t *)&extrah = dp->seq_rcv; */ 1217 if (!dp->shortseq) 1218 extrah_len = 8; 1219 else { 1220 extrah_len = 4; 1221 use_shortseq = 1; 1222 } 1223 } else if (dp->ack_snd) { 1224 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_ACK!\n")); 1225 type = DCCP_TYPE_ACK; 1226 if (!dp->shortseq) 1227 extrah_len = 8; 1228 else { 1229 extrah_len = 4; 1230 use_shortseq = 1; 1231 } 1232 } else if (len) { 1233 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_DATA!\n")); 1234 type = DCCP_TYPE_DATA; 1235 extrah_len = 0; 1236 } else { 1237 DCCP_DEBUG((LOG_INFO, "No ack or data to send!\n")); 1238 return 0; 1239 } 1240 } else if (dp->state == DCCPS_CLIENT_CLOSE) { 1241 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_CLOSE!\n")); 1242 type = DCCP_TYPE_CLOSE; 1243 extrah_len = 8; 1244 } else if (dp->state == DCCPS_SERVER_CLOSE) { 1245 DCCP_DEBUG((LOG_INFO, "Sending DCCP TYPE_CLOSEREQ!\n")); 1246 type = DCCP_TYPE_CLOSEREQ; 1247 extrah_len = 8; 1248 } else { 1249 DCCP_DEBUG((LOG_INFO, "Hey, we should never get here, state = %u\n", dp->state)); 1250 return 1; 1251 } 1252 1253 /* Adding options. */ 1254 if (dp->optlen) { 1255 DCCP_DEBUG((LOG_INFO, "Copying options from dp->options! %u\n", dp->optlen)); 1256 memcpy(options, dp->options, dp->optlen); 1257 optlen = dp->optlen; 1258 dp->optlen = 0; 1259 } 1260 1261 if (dp->featlen && (optlen + dp->featlen < DCCP_MAX_OPTIONS)) { 1262 DCCP_DEBUG((LOG_INFO, "Copying options from dp->features! %u\n", dp->featlen)); 1263 memcpy(options + optlen, dp->features, dp->featlen); 1264 optlen += dp->featlen; 1265 } 1266 1267 t = optlen % 4; 1268 1269 if (t) { 1270 t = 4 - t; 1271 for (i = 0 ; i<t; i++) { 1272 options[optlen] = 0; 1273 optlen++; 1274 } 1275 } 1276 1277 #ifdef INET6 1278 if (isipv6) { 1279 DCCP_DEBUG((LOG_INFO, "Sending ipv6 packet...\n")); 1280 if (!use_shortseq) 1281 hdrlen = sizeof(struct ip6_hdr) + sizeof(struct dccplhdr) + 1282 extrah_len + optlen; 1283 else 1284 hdrlen = sizeof(struct ip6_hdr) + sizeof(struct dccphdr) + 1285 extrah_len + optlen; 1286 } else 1287 #endif 1288 { 1289 if (!use_shortseq) 1290 hdrlen = sizeof(struct ip) + sizeof(struct dccplhdr) + 1291 extrah_len + optlen; 1292 else 1293 hdrlen = sizeof(struct ip) + sizeof(struct dccphdr) + 1294 extrah_len + optlen; 1295 } 1296 DCCP_DEBUG((LOG_INFO, "Pkt headerlen %u\n", hdrlen)); 1297 1298 if (len > (dp->d_maxseg - extrah_len - optlen)) { 1299 len = dp->d_maxseg - extrah_len - optlen; 1300 sendalot = 1; 1301 } 1302 1303 MGETHDR(m, M_DONTWAIT, MT_HEADER); 1304 if (m == NULL) { 1305 error = ENOBUFS; 1306 goto release; 1307 } 1308 if (MHLEN < hdrlen + max_linkhdr) { 1309 MCLGET(m, M_DONTWAIT); 1310 if ((m->m_flags & M_EXT) == 0) { 1311 error = ENOBUFS; 1312 goto release; 1313 } 1314 } 1315 1316 m->m_data += max_linkhdr; 1317 m->m_len = hdrlen; 1318 1319 if (len) { /* We have data to send */ 1320 if (len <= M_TRAILINGSPACE(m) - hdrlen) { 1321 m_copydata(so->so_snd.sb_mb, off, (int) len, 1322 mtod(m, char *) + hdrlen); 1323 m->m_len += len; 1324 } else { 1325 m->m_next = m_copym(so->so_snd.sb_mb, off, 1326 (int)len, M_DONTWAIT); 1327 if (m->m_next == 0) { 1328 error = ENOBUFS; 1329 goto release; 1330 } 1331 } 1332 } else { 1333 dp->ndp++; 1334 } 1335 1336 m_reset_rcvif(m); 1337 1338 if (!isipv6 && (len + hdrlen) > IP_MAXPACKET) { 1339 error = EMSGSIZE; 1340 goto release; 1341 } 1342 1343 /* 1344 * Fill in mbuf with extended DCCP header 1345 * and addresses and length put into network format. 1346 */ 1347 #ifdef INET6 1348 if (isipv6) { 1349 ip6 = mtod(m, struct ip6_hdr *); 1350 dh = (struct dccphdr *)(ip6 + 1); 1351 ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) | 1352 (in6p_flowinfo(inp) & IPV6_FLOWINFO_MASK); 1353 ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) | 1354 (IPV6_VERSION & IPV6_VERSION_MASK); 1355 ip6->ip6_nxt = IPPROTO_DCCP; 1356 ip6->ip6_src = in6p_laddr(inp); 1357 ip6->ip6_dst = in6p_faddr(inp); 1358 } else 1359 #endif 1360 { 1361 ip = mtod(m, struct ip *); 1362 dh = (struct dccphdr *)(ip + 1); 1363 memset(ip, 0, sizeof(struct ip)); 1364 ip->ip_p = IPPROTO_DCCP; 1365 ip->ip_src = in4p_laddr(inp); 1366 ip->ip_dst = in4p_faddr(inp); 1367 } 1368 dlh = (struct dccplhdr *)dh; 1369 1370 dh->dh_sport = inp->inp_lport; 1371 dh->dh_dport = inp->inp_fport; 1372 dh->dh_cscov = dp->cslen; 1373 dh->dh_ccval = dp->ccval; 1374 dh->dh_type = type; 1375 dh->dh_res = 0; /* Reserved field should be zero */ 1376 if (!use_shortseq) { 1377 dlh->dh_res2 = 0; /* Reserved field should be zero */ 1378 dh->dh_off = 4 + (extrah_len / 4) + (optlen / 4); 1379 } else 1380 dh->dh_off = 3 + (extrah_len / 4) + (optlen / 4); 1381 1382 dp->seq_snd = (dp->seq_snd +1) % 281474976710656LL; 1383 if (!use_shortseq) { 1384 DSEQ_TO_DHDR(dlh, dp->seq_snd); 1385 dlh->dh_x = 1; 1386 } else { 1387 /* short sequene number */ 1388 dh->dh_seq = htonl(dp->seq_snd) >> 8; 1389 dh->dh_x = 0; 1390 } 1391 1392 if (!use_shortseq) { 1393 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 } else { 1395 DCCP_DEBUG((LOG_INFO, "Sending with seq %x, (dp->seq_snd = %llu)\n\n", dh->dh_seq, dp->seq_snd)); 1396 } 1397 1398 if (dh->dh_type == DCCP_TYPE_REQUEST) { 1399 drqh = (struct dccp_requesthdr *)(dlh + 1); 1400 drqh->drqh_scode = dp->scode; 1401 optp = (u_char *)(drqh + 1); 1402 } else if (dh->dh_type == DCCP_TYPE_RESET) { 1403 drth = (struct dccp_resethdr *)(dlh + 1); 1404 drth->drth_dash.dah_res = 0; 1405 DSEQ_TO_DAHDR(drth->drth_dash, dp->seq_rcv); 1406 if (dp->state == DCCPS_SERVER_CLOSE) 1407 drth->drth_reason = 1; 1408 else 1409 drth->drth_reason = 2; 1410 drth->drth_data1 = 0; 1411 drth->drth_data2 = 0; 1412 drth->drth_data3 = 0; 1413 optp = (u_char *)(drth + 1); 1414 } else if (extrah_len) { 1415 if (!use_shortseq){ 1416 dalh = (struct dccp_acklhdr *)(dlh + 1); 1417 dalh->dash.dah_res = 0; /* Reserved field should be zero */ 1418 1419 if (dp->state == DCCPS_ESTAB) { 1420 DSEQ_TO_DAHDR(dalh->dash, dp->ack_snd); 1421 dp->ack_snd = 0; 1422 } else { 1423 DSEQ_TO_DAHDR(dalh->dash, dp->seq_rcv); 1424 } 1425 1426 if (dh->dh_type == DCCP_TYPE_RESPONSE) { 1427 DCCP_DEBUG((LOG_INFO, "Sending dccp type response\n")); 1428 drqh = (struct dccp_requesthdr *)(dalh + 1); 1429 drqh->drqh_scode = dp->scode; 1430 optp = (u_char *)(drqh + 1); 1431 } else 1432 optp = (u_char *)(dalh + 1); 1433 } else { 1434 /* XXX shortseq */ 1435 dah = (struct dccp_ackhdr *)(dh + 1); 1436 dah->dash.dah_res = 0; /* Reserved field should be zero */ 1437 dah->dash.dah_ack = htonl(dp->seq_rcv) >> 8; 1438 optp = (u_char *)(dah + 1); 1439 } 1440 1441 } else { 1442 optp = (u_char *)(dlh + 1); 1443 } 1444 1445 if (optlen) 1446 memcpy(optp, options, optlen); 1447 1448 m->m_pkthdr.len = hdrlen + len; 1449 1450 if (dh->dh_cscov == 0) { 1451 #ifdef INET6 1452 if (isipv6) 1453 cslen = (hdrlen - sizeof(struct ip6_hdr)) + len; 1454 else 1455 cslen = (hdrlen - sizeof(struct ip)) + len; 1456 #else 1457 cslen = (hdrlen - sizeof(struct ip)) + len; 1458 #endif 1459 } else { 1460 cslen = dh->dh_off * 4 + (dh->dh_cscov - 1) * 4; 1461 #ifdef INET6 1462 if (isipv6) { 1463 if (cslen > (hdrlen - sizeof(struct ip6_hdr)) + len) 1464 cslen = (hdrlen - sizeof(struct ip6_hdr)) + len; 1465 } else { 1466 if (cslen > (hdrlen - sizeof(struct ip)) + len) 1467 cslen = (hdrlen - sizeof(struct ip)) + len; 1468 } 1469 #else 1470 if (cslen > (hdrlen - sizeof(struct ip)) + len) 1471 cslen = (hdrlen - sizeof(struct ip)) + len; 1472 #endif 1473 } 1474 1475 /* 1476 * Set up checksum 1477 */ 1478 m->m_pkthdr.csum_flags = 0; 1479 1480 dh->dh_sum = 0; 1481 #ifdef INET6 1482 if (isipv6) { 1483 dh->dh_sum = in6_cksum(m, IPPROTO_DCCP, sizeof(struct ip6_hdr), 1484 cslen); 1485 } else 1486 #endif 1487 { 1488 ip->ip_len = htons(hdrlen + len); 1489 ip->ip_ttl = dp->inp_ip_ttl; /* XXX */ 1490 ip->ip_tos = dp->inp_ip_tos; /* XXX */ 1491 1492 dh->dh_sum = in4_cksum(m, IPPROTO_DCCP, sizeof(struct ip), 1493 cslen); 1494 #ifndef __OpenBSD__ 1495 m->m_pkthdr.csum_data = offsetof(struct dccphdr, dh_sum); 1496 #endif 1497 } 1498 1499 dccpstat.dccps_opackets++; 1500 dccpstat.dccps_obytes += m->m_pkthdr.len; 1501 1502 #ifdef INET6 1503 if (isipv6) { 1504 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 1506 error = ip6_output(m, in6p_outputopts(inp), &inp->inp_route, 1507 (inp->inp_socket->so_options & SO_DONTROUTE), NULL, NULL, 1508 NULL); 1509 } else 1510 #endif 1511 { 1512 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 error = ip_output(m, inp->inp_options, &inp->inp_route, 1514 (inp->inp_socket->so_options & SO_DONTROUTE), 0, 1515 inp); 1516 } 1517 1518 if (error) { 1519 DCCP_DEBUG((LOG_INFO, "IP output failed! %d\n", error)); 1520 return (error); 1521 } 1522 1523 sbdrop(&inp->inp_socket->so_snd, len); 1524 sowwakeup(inp->inp_socket); 1525 1526 if (dp->cc_in_use[0] > 0 && dp->state == DCCPS_ESTAB) { 1527 DCCP_DEBUG((LOG_INFO, "Calling *cc_sw[%u].cc_send_packet_sent!\n", dp->cc_in_use[0])); 1528 if (sendalot) { 1529 (*cc_sw[dp->cc_in_use[0]].cc_send_packet_sent)(dp->cc_state[0], 1,len); 1530 goto again; 1531 } else { 1532 (*cc_sw[dp->cc_in_use[0]].cc_send_packet_sent)(dp->cc_state[0], 0,len); 1533 } 1534 } else { 1535 if (sendalot) 1536 goto again; 1537 } 1538 1539 DCCP_DEBUG((LOG_INFO, "dccp_output finished\n")); 1540 1541 return (0); 1542 1543 release: 1544 m_freem(m); 1545 return (error); 1546 } 1547 1548 int 1549 dccp_abort(struct socket *so) 1550 { 1551 struct inpcb *inp = NULL; 1552 struct dccpcb *dp; 1553 1554 DCCP_DEBUG((LOG_INFO, "Entering dccp_abort!\n")); 1555 INP_INFO_WLOCK(&dccpbinfo); 1556 inp = sotoinpcb(so); 1557 if (inp == NULL) { 1558 INP_INFO_WUNLOCK(&dccpbinfo); 1559 return EINVAL; 1560 } 1561 dp = inp->inp_ppcb; 1562 1563 dccp_disconnect2(dp); 1564 1565 INP_INFO_WUNLOCK(&dccpbinfo); 1566 return 0; 1567 } 1568 1569 static struct dccpcb * 1570 dccp_close(struct dccpcb *dp) 1571 { 1572 struct socket *so; 1573 struct inpcb *inp = dp->d_inpcb; 1574 so = dptosocket(dp); 1575 1576 DCCP_DEBUG((LOG_INFO, "Entering dccp_close!\n")); 1577 1578 /* Stop all timers */ 1579 callout_stop(&dp->connect_timer); 1580 callout_stop(&dp->retrans_timer); 1581 callout_stop(&dp->close_timer); 1582 callout_stop(&dp->timewait_timer); 1583 1584 if (dp->cc_in_use[0] > 0) 1585 (*cc_sw[dp->cc_in_use[0]].cc_send_free)(dp->cc_state[0]); 1586 if (dp->cc_in_use[1] > 0) 1587 (*cc_sw[dp->cc_in_use[1]].cc_recv_free)(dp->cc_state[1]); 1588 1589 pool_put(&dccpcb_pool, dp); 1590 inp->inp_ppcb = NULL; 1591 soisdisconnected(so); 1592 inpcb_destroy(inp); 1593 return ((struct dccpcb *)0); 1594 } 1595 1596 /* 1597 * Runs when a new socket is created with the 1598 * socket system call or sonewconn. 1599 */ 1600 int 1601 dccp_attach(struct socket *so, int proto) 1602 { 1603 struct inpcb *inp = NULL; 1604 struct dccpcb *dp; 1605 int s, error = 0; 1606 1607 DCCP_DEBUG((LOG_INFO, "Entering dccp_attach(proto=%d)!\n", proto)); 1608 INP_INFO_WLOCK(&dccpbinfo); 1609 s = splsoftnet(); 1610 sosetlock(so); 1611 1612 inp = sotoinpcb(so); 1613 if (inp != 0) { 1614 error = EINVAL; 1615 goto out; 1616 } 1617 error = soreserve(so, dccp_sendspace, dccp_recvspace); 1618 if (error) 1619 goto out; 1620 error = inpcb_create(so, &dccpbtable); 1621 if (error) 1622 goto out; 1623 inp = sotoinpcb(so); 1624 1625 dp = dccp_newdccpcb(inp->inp_af, inp); 1626 if (dp == 0) { 1627 int nofd = so->so_state & SS_NOFDREF; 1628 so->so_state &= ~SS_NOFDREF; 1629 inpcb_destroy(inp); 1630 so->so_state |= nofd; 1631 error = ENOBUFS; 1632 goto out; 1633 } 1634 1635 #ifdef INET6 1636 if (proto == PF_INET6) { 1637 DCCP_DEBUG((LOG_INFO, "We are an ipv6 socket!!!\n")); 1638 dp->inp_vflag |= INP_IPV6; 1639 } else 1640 #endif 1641 dp->inp_vflag |= INP_IPV4; 1642 dp->inp_ip_ttl = ip_defttl; 1643 1644 dp->state = DCCPS_CLOSED; 1645 out: 1646 splx(s); 1647 INP_INFO_WUNLOCK(&dccpbinfo); 1648 return error; 1649 } 1650 1651 static int 1652 dccp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 1653 { 1654 struct inpcb *inp; 1655 int error; 1656 int s; 1657 struct sockaddr_in *sin = (struct sockaddr_in *)nam; 1658 1659 DCCP_DEBUG((LOG_INFO, "Entering dccp_bind!\n")); 1660 INP_INFO_WLOCK(&dccpbinfo); 1661 inp = sotoinpcb(so); 1662 if (inp == 0) { 1663 INP_INFO_WUNLOCK(&dccpbinfo); 1664 return EINVAL; 1665 } 1666 1667 /* Do not bind to multicast addresses! */ 1668 if (sin->sin_family == AF_INET && 1669 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 1670 INP_INFO_WUNLOCK(&dccpbinfo); 1671 return EAFNOSUPPORT; 1672 } 1673 INP_LOCK(inp); 1674 s = splsoftnet(); 1675 error = inpcb_bind(inp, sin, l); 1676 splx(s); 1677 INP_UNLOCK(inp); 1678 INP_INFO_WUNLOCK(&dccpbinfo); 1679 return error; 1680 } 1681 1682 /* 1683 * Initiates a connection to a server 1684 * Called by the connect system call. 1685 */ 1686 static int 1687 dccp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 1688 { 1689 struct inpcb *inp; 1690 struct dccpcb *dp; 1691 int error; 1692 struct sockaddr_in *sin; 1693 char test[2]; 1694 1695 DCCP_DEBUG((LOG_INFO, "Entering dccp_connect!\n")); 1696 1697 INP_INFO_WLOCK(&dccpbinfo); 1698 inp = sotoinpcb(so); 1699 if (inp == 0) { 1700 INP_INFO_WUNLOCK(&dccpbinfo); 1701 return EINVAL; 1702 } 1703 INP_LOCK(inp); 1704 if (in4p_faddr(inp).s_addr != INADDR_ANY) { 1705 INP_UNLOCK(inp); 1706 INP_INFO_WUNLOCK(&dccpbinfo); 1707 return EISCONN; 1708 } 1709 1710 dp = (struct dccpcb *)inp->inp_ppcb; 1711 1712 if (dp->state == DCCPS_ESTAB) { 1713 DCCP_DEBUG((LOG_INFO, "Why are we in connect when we already have an established connection?\n")); 1714 } 1715 1716 dp->who = DCCP_CLIENT; 1717 dp->seq_snd = (((u_int64_t)random() << 32) | random()) % 281474976710656LL; 1718 dp->ref_seq.hi = dp->seq_snd >> 24; 1719 dp->ref_seq.lo = (u_int64_t)(dp->seq_snd & 0xffffff); 1720 DCCP_DEBUG((LOG_INFO, "dccp_connect seq_snd %llu\n", dp->seq_snd)); 1721 1722 dccpstat.dccps_connattempt++; 1723 1724 sin = (struct sockaddr_in *)nam; 1725 if (sin->sin_family == AF_INET 1726 && IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 1727 error = EAFNOSUPPORT; 1728 goto bad; 1729 } 1730 1731 error = dccp_doconnect(so, nam, l, 0); 1732 1733 if (error != 0) 1734 goto bad; 1735 1736 callout_reset(&dp->retrans_timer, dp->retrans, dccp_retrans_t, dp); 1737 callout_reset(&dp->connect_timer, DCCP_CONNECT_TIMER, dccp_connect_t, dp); 1738 1739 if (dccp_do_feature_nego){ 1740 test[0] = dp->pref_cc; 1741 dccp_add_feature(dp, DCCP_OPT_CHANGE_R, DCCP_FEATURE_CC, test, 1); 1742 } 1743 1744 error = dccp_output(dp, 0); 1745 1746 bad: 1747 INP_UNLOCK(inp); 1748 INP_INFO_WUNLOCK(&dccpbinfo); 1749 return error; 1750 } 1751 1752 static int 1753 dccp_connect2(struct socket *so, struct socket *so2) 1754 { 1755 KASSERT(solocked(so)); 1756 1757 return EOPNOTSUPP; 1758 } 1759 1760 /* 1761 * 1762 * 1763 */ 1764 int 1765 dccp_doconnect(struct socket *so, struct sockaddr *nam, 1766 struct lwp *l, int isipv6) 1767 { 1768 struct inpcb *inp; 1769 int error = 0; 1770 1771 DCCP_DEBUG((LOG_INFO, "Entering dccp_doconnect!\n")); 1772 1773 inp = sotoinpcb(so); 1774 1775 if (inp->inp_lport == 0) { 1776 #ifdef INET6 1777 if (isipv6) { 1778 DCCP_DEBUG((LOG_INFO, "Running in6pcb_bind!\n")); 1779 error = in6pcb_bind(inp, NULL, l); 1780 } else 1781 #endif /* INET6 */ 1782 { 1783 error = inpcb_bind(inp, NULL, l); 1784 } 1785 if (error) { 1786 DCCP_DEBUG((LOG_INFO, "inpcb_bind=%d\n",error)); 1787 return error; 1788 } 1789 } 1790 1791 #ifdef INET6 1792 if (isipv6) { 1793 error = in6pcb_connect(inp, (struct sockaddr_in6 *)nam, l); 1794 DCCP_DEBUG((LOG_INFO, "in6pcb_connect=%d\n",error)); 1795 } else 1796 #endif 1797 error = inpcb_connect(inp, (struct sockaddr_in *)nam, l); 1798 if (error) { 1799 DCCP_DEBUG((LOG_INFO, "inpcb_connect=%d\n",error)); 1800 return error; 1801 } 1802 1803 soisconnecting(so); 1804 return error; 1805 } 1806 1807 /* 1808 * Detaches the DCCP protocol from the socket. 1809 * 1810 */ 1811 int 1812 dccp_detach(struct socket *so) 1813 { 1814 struct inpcb *inp; 1815 struct dccpcb *dp; 1816 1817 DCCP_DEBUG((LOG_INFO, "Entering dccp_detach!\n")); 1818 inp = sotoinpcb(so); 1819 if (inp == NULL) { 1820 return EINVAL; 1821 } 1822 dp = inp->inp_ppcb; 1823 if (! dccp_disconnect2(dp)) { 1824 INP_UNLOCK(inp); 1825 } 1826 INP_INFO_WUNLOCK(&dccpbinfo); 1827 return 0; 1828 } 1829 1830 /* 1831 * 1832 * 1833 */ 1834 int 1835 dccp_disconnect(struct socket *so) 1836 { 1837 struct inpcb *inp; 1838 struct dccpcb *dp; 1839 1840 DCCP_DEBUG((LOG_INFO, "Entering dccp_disconnect!\n")); 1841 INP_INFO_WLOCK(&dccpbinfo); 1842 #ifndef __NetBSD__ 1843 inp = sotoinpcb(so); 1844 if (inp == 0) { 1845 INP_INFO_WUNLOCK(&dccpbinfo); 1846 return EINVAL; 1847 } 1848 INP_LOCK(inp); 1849 if (in4p_faddr(inp).s_addr == INADDR_ANY) { 1850 INP_INFO_WUNLOCK(&dccpbinfo); 1851 INP_UNLOCK(inp); 1852 return ENOTCONN; 1853 } 1854 1855 dp = (struct dccpcb *)inp->inp_ppcb; 1856 #else /* NetBSD */ 1857 inp = sotoinpcb(so); 1858 if (inp == NULL) { 1859 INP_INFO_WUNLOCK(&dccpbinfo); 1860 return EINVAL; 1861 } 1862 dp = inp->inp_ppcb; 1863 #endif 1864 if (!dccp_disconnect2(dp)) { 1865 INP_UNLOCK(inp); 1866 } 1867 INP_INFO_WUNLOCK(&dccpbinfo); 1868 return 0; 1869 } 1870 1871 /* 1872 * If we have don't have an established connection 1873 * we can call dccp_close, otherwise we can just 1874 * set SS_ISDISCONNECTED and flush the receive queue. 1875 */ 1876 static int 1877 dccp_disconnect2(struct dccpcb *dp) 1878 { 1879 struct socket *so = dptosocket(dp); 1880 1881 DCCP_DEBUG((LOG_INFO, "Entering dccp_disconnect2!\n")); 1882 1883 if (dp->state < DCCPS_ESTAB) { 1884 dccp_close(dp); 1885 return 1; 1886 } else { 1887 soisdisconnecting(so); 1888 sbflush(&so->so_rcv); 1889 if (dp->state == DCCPS_ESTAB) { 1890 dp->retrans = 100; 1891 callout_reset(&dp->retrans_timer, dp->retrans, 1892 dccp_retrans_t, dp); 1893 callout_reset(&dp->close_timer, DCCP_CLOSE_TIMER, 1894 dccp_close_t, dp); 1895 if (dp->who == DCCP_CLIENT) { 1896 dp->state = DCCPS_CLIENT_CLOSE; 1897 } else { 1898 dp->state = DCCPS_SERVER_CLOSE; 1899 } 1900 dccp_output(dp, 0); 1901 } 1902 } 1903 return 0; 1904 } 1905 1906 int 1907 dccp_send(struct socket *so, struct mbuf *m, struct sockaddr *addr, 1908 struct mbuf *control, struct lwp *l) 1909 { 1910 struct inpcb *inp; 1911 struct dccpcb *dp; 1912 int error = 0; 1913 int isipv6 = 0; 1914 1915 DCCP_DEBUG((LOG_INFO, "Entering dccp_send!\n")); 1916 KASSERT(solocked(so)); 1917 KASSERT(m != NULL); 1918 1919 if (control && control->m_len) { 1920 m_freem(control); 1921 m_freem(m); 1922 return EINVAL; 1923 } 1924 1925 #ifdef INET6 1926 isipv6 = addr && addr->sa_family == AF_INET6; 1927 #endif 1928 1929 INP_INFO_WLOCK(&dccpbinfo); 1930 inp = sotoinpcb(so); 1931 if (inp == NULL) { 1932 error = EINVAL; 1933 goto release; 1934 } 1935 INP_LOCK(inp); 1936 dp = inp->inp_ppcb; 1937 1938 if (dp->state != DCCPS_ESTAB) { 1939 DCCP_DEBUG((LOG_INFO, "We have no established connection!\n")); 1940 } 1941 1942 if (control != NULL) { 1943 DCCP_DEBUG((LOG_INFO, "We got a control message!\n")); 1944 /* Are we going to use control messages??? */ 1945 if (control->m_len) { 1946 m_freem(control); 1947 } 1948 } 1949 1950 if (sbspace_oob(&so->so_snd) == 0) { 1951 INP_UNLOCK(inp); 1952 error = ENOBUFS; 1953 goto release; 1954 } 1955 1956 if (m->m_pkthdr.len > dp->d_maxseg) { 1957 /* XXX we should calculate packet size more carefully */ 1958 INP_UNLOCK(inp); 1959 error = EINVAL; 1960 goto release; 1961 } 1962 1963 if (dp->pktcnt >= DCCP_MAX_PKTS) { 1964 INP_UNLOCK(inp); 1965 error = ENOBUFS; 1966 goto release; 1967 } 1968 1969 sbappend(&so->so_snd, m); 1970 dp->pktlen[(dp->pktlenidx + dp->pktcnt) % DCCP_MAX_PKTS] = m->m_pkthdr.len; 1971 dp->pktcnt ++; 1972 1973 if (addr && dp->state == DCCPS_CLOSED) { 1974 error = dccp_doconnect(so, addr, l, isipv6); 1975 if (error) 1976 goto out; 1977 } 1978 1979 error = dccp_output(dp, 0); 1980 1981 out: 1982 INP_UNLOCK(inp); 1983 INP_INFO_WUNLOCK(&dccpbinfo); 1984 return error; 1985 1986 release: 1987 INP_INFO_WUNLOCK(&dccpbinfo); 1988 m_freem(m); 1989 return (error); 1990 } 1991 1992 /* 1993 * Sets socket to SS_CANTSENDMORE 1994 */ 1995 int 1996 dccp_shutdown(struct socket *so) 1997 { 1998 struct inpcb *inp; 1999 2000 DCCP_DEBUG((LOG_INFO, "Entering dccp_shutdown!\n")); 2001 INP_INFO_RLOCK(&dccpbinfo); 2002 inp = sotoinpcb(so); 2003 if (inp == 0) { 2004 INP_INFO_RUNLOCK(&dccpbinfo); 2005 return EINVAL; 2006 } 2007 INP_LOCK(inp); 2008 INP_INFO_RUNLOCK(&dccpbinfo); 2009 socantsendmore(so); 2010 INP_UNLOCK(inp); 2011 return 0; 2012 } 2013 2014 static int 2015 dccp_listen(struct socket *so, struct lwp *td) 2016 { 2017 struct inpcb *inp; 2018 struct dccpcb *dp; 2019 int error = 0; 2020 2021 DCCP_DEBUG((LOG_INFO, "Entering dccp_listen!\n")); 2022 2023 INP_INFO_RLOCK(&dccpbinfo); 2024 inp = sotoinpcb(so); 2025 if (inp == 0) { 2026 INP_INFO_RUNLOCK(&dccpbinfo); 2027 return EINVAL; 2028 } 2029 INP_LOCK(inp); 2030 INP_INFO_RUNLOCK(&dccpbinfo); 2031 dp = (struct dccpcb *)inp->inp_ppcb; 2032 if (inp->inp_lport == 0) 2033 error = inpcb_bind(inp, NULL, td); 2034 if (error == 0) { 2035 dp->state = DCCPS_LISTEN; 2036 dp->who = DCCP_LISTENER; 2037 } 2038 INP_UNLOCK(inp); 2039 return error; 2040 } 2041 2042 /* 2043 * Accepts a connection (accept system call) 2044 */ 2045 static int 2046 dccp_accept(struct socket *so, struct sockaddr *nam) 2047 { 2048 struct inpcb *inp = NULL; 2049 int error = 0; 2050 2051 DCCP_DEBUG((LOG_INFO, "Entering dccp_accept!\n")); 2052 2053 if (nam == NULL) { 2054 return EINVAL; 2055 } 2056 if (so->so_state & SS_ISDISCONNECTED) { 2057 DCCP_DEBUG((LOG_INFO, "so_state && SS_ISDISCONNECTED!, so->state = %i\n", so->so_state)); 2058 return ECONNABORTED; 2059 } 2060 2061 INP_INFO_RLOCK(&dccpbinfo); 2062 inp = sotoinpcb(so); 2063 if (inp == 0) { 2064 INP_INFO_RUNLOCK(&dccpbinfo); 2065 return EINVAL; 2066 } 2067 INP_LOCK(inp); 2068 INP_INFO_RUNLOCK(&dccpbinfo); 2069 inpcb_fetch_peeraddr(inp, (struct sockaddr_in *)nam); 2070 2071 return error; 2072 } 2073 2074 /* 2075 * Initializes a new DCCP control block 2076 * (inpcb_create in attach has already allocated memory for it) 2077 */ 2078 struct dccpcb * 2079 dccp_newdccpcb(int family, void *aux) 2080 { 2081 struct inpcb *inp; 2082 struct dccpcb *dp; 2083 2084 DCCP_DEBUG((LOG_INFO, "Creating a new dccpcb!\n")); 2085 2086 dp = pool_get(&dccpcb_pool, PR_NOWAIT); 2087 if (dp == NULL) 2088 return NULL; 2089 memset((char *) dp, 0, sizeof(struct dccpcb)); 2090 2091 callout_init(&dp->connect_timer, 0); 2092 callout_init(&dp->retrans_timer, 0); 2093 callout_init(&dp->close_timer, 0); 2094 callout_init(&dp->timewait_timer, 0); 2095 2096 dp->ndp = 0; 2097 dp->loss_window = 1000; 2098 dp->cslen = 0; 2099 dp->pref_cc = DEFAULT_CCID; 2100 dp->who = DCCP_UNDEF; 2101 dp->seq_snd = 0; 2102 dp->seq_rcv = 0; 2103 dp->shortseq = 0; 2104 dp->gsn_rcv = 281474976710656LL; 2105 dp->optlen = 0; 2106 if (dccp_do_feature_nego){ 2107 dp->cc_in_use[0] = -1; 2108 dp->cc_in_use[1] = -1; 2109 } else { 2110 /* for compatibility with linux */ 2111 dp->cc_in_use[0] = 4; 2112 dp->cc_in_use[1] = 4; 2113 } 2114 dp->av_size = 0; /* no ack vector initially */ 2115 dp->remote_ackvector = 0; /* no ack vector on remote side initially */ 2116 dp->retrans = 200; 2117 dp->avgpsize = 0; 2118 dp->d_maxseg = 1400; 2119 dp->ref_pseq.hi = 0; 2120 dp->ref_pseq.lo = 0; 2121 dp->pktlenidx = 0; 2122 dp->pktcnt = 0; 2123 2124 inp = (struct inpcb *)aux; 2125 dp->d_inpcb = inp; 2126 inp->inp_ppcb = dp; 2127 switch (family) { 2128 case PF_INET: 2129 in4p_ip(inp).ip_ttl = ip_defttl; 2130 break; 2131 case PF_INET6: 2132 in6p_ip6(inp).ip6_hlim = in6pcb_selecthlim_rt(inp); 2133 break; 2134 } 2135 2136 if (!dccp_do_feature_nego){ 2137 dp->cc_state[0] = (*cc_sw[4].cc_send_init)(dp); 2138 dp->cc_state[1] = (*cc_sw[4].cc_recv_init)(dp); 2139 } 2140 2141 return dp; 2142 } 2143 2144 int 2145 dccp_add_option(struct dccpcb *dp, u_int8_t opt, char *val, u_int8_t val_len) 2146 { 2147 return dccp_add_feature_option(dp, opt, 0, val, val_len); 2148 } 2149 2150 int 2151 dccp_add_feature_option(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, char *val, u_int8_t val_len) 2152 { 2153 int i; 2154 DCCP_DEBUG((LOG_INFO, "Entering dccp_add_feature_option, opt = %u, val_len = %u optlen %u\n", opt, val_len, dp->optlen)); 2155 2156 if (DCCP_MAX_OPTIONS > (dp->optlen + val_len + 2)) { 2157 dp->options[dp->optlen] = opt; 2158 if (opt < 32) { 2159 dp->optlen++; 2160 } else { 2161 if (opt == DCCP_OPT_CONFIRM_L && val_len) { 2162 dp->options[dp->optlen + 1] = val_len + 3; 2163 dp->options[dp->optlen +2] = feature; 2164 dp->optlen += 3; 2165 } else { 2166 dp->options[dp->optlen + 1] = val_len + 2; 2167 dp->optlen += 2; 2168 } 2169 2170 for (i = 0; i<val_len; i++) { 2171 dp->options[dp->optlen] = val[i]; 2172 dp->optlen++; 2173 } 2174 } 2175 } else { 2176 DCCP_DEBUG((LOG_INFO, "No room for more options, optlen = %u\n", dp->optlen)); 2177 return -1; 2178 } 2179 2180 return 0; 2181 } 2182 2183 /* 2184 * Searches "options" for given option type. if found, the data is copied to buffer 2185 * and returns the data length. 2186 * Returns 0 if option type not found 2187 */ 2188 int 2189 dccp_get_option(char *options, int optlen, int type, char *buffer, int buflen) 2190 { 2191 int i, j, size; 2192 u_int8_t t; 2193 2194 for (i=0; i < optlen;) { 2195 t = options[i++]; 2196 if (t >= 32) { 2197 size = options[i++] - 2; 2198 if (t == type) { 2199 if (size > buflen) 2200 return 0; 2201 for (j = 0; j < size; j++) 2202 buffer[j] = options[i++]; 2203 return size; 2204 } 2205 i += size; 2206 } 2207 } 2208 /* If we get here the options was not found */ 2209 DCCP_DEBUG((LOG_INFO, "dccp_get_option option(%d) not found\n", type)); 2210 return 0; 2211 } 2212 2213 void 2214 dccp_parse_options(struct dccpcb *dp, char *options, int optlen) 2215 { 2216 u_int8_t opt, size, i, j; 2217 char val[8]; 2218 2219 for (i = 0; i < optlen; i++) { 2220 opt = options[i]; 2221 2222 DCCP_DEBUG((LOG_INFO, "Parsing opt: 0x%02x\n", opt)); 2223 2224 if (opt < 32) { 2225 switch (opt) { 2226 case DCCP_OPT_PADDING: 2227 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_PADDING!\n")); 2228 break; 2229 case DCCP_OPT_DATA_DISCARD: 2230 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_DATA_DISCARD!\n")); 2231 break; 2232 case DCCP_OPT_SLOW_RECV: 2233 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_SLOW_RECV!\n")); 2234 break; 2235 case DCCP_OPT_BUF_CLOSED: 2236 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_BUF_CLOSED!\n")); 2237 break; 2238 default: 2239 DCCP_DEBUG((LOG_INFO, "Got an unknown option, option = %u!\n", opt)); 2240 } 2241 } else if (opt > 32 && opt < 36) { 2242 size = options[i+ 1]; 2243 if (size < 3 || size > 10) { 2244 DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2245 return; 2246 } 2247 /* Feature negotiations are options 33 to 35 */ 2248 DCCP_DEBUG((LOG_INFO, "Got option %u, size = %u, feature = %u\n", opt, size, options[i+2])); 2249 memcpy(val, options + i + 3, size -3); 2250 DCCP_DEBUG((LOG_INFO, "Calling dccp_feature neg(%u, %u, options[%u + 1], %u)!\n", (u_int)dp, opt, i+ 1, (size - 3))); 2251 dccp_feature_neg(dp, opt, options[i+2], (size -3) , val); 2252 i += size - 1; 2253 2254 } else if (opt < 128) { 2255 size = options[i+ 1]; 2256 if (size < 3 || size > 10) { 2257 DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2258 return; 2259 } 2260 2261 switch (opt) { 2262 case DCCP_OPT_RECV_BUF_DROPS: 2263 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_RECV_BUF_DROPS, size = %u!\n", size)); 2264 for (j=2; j < size; j++) { 2265 DCCP_DEBUG((LOG_INFO, "val[%u] = %u ", j-1, options[i+j])); 2266 } 2267 DCCP_DEBUG((LOG_INFO, "\n")); 2268 break; 2269 2270 case DCCP_OPT_TIMESTAMP: 2271 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_TIMESTAMP, size = %u\n", size)); 2272 2273 /* Adding TimestampEcho to next outgoing */ 2274 memcpy(val, options + i + 2, 4); 2275 memset(val + 4, 0, 4); 2276 dccp_add_option(dp, DCCP_OPT_TIMESTAMP_ECHO, val, 8); 2277 break; 2278 2279 case DCCP_OPT_TIMESTAMP_ECHO: 2280 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_TIMESTAMP_ECHO, size = %u\n",size)); 2281 for (j=2; j < size; j++) { 2282 DCCP_DEBUG((LOG_INFO, "val[%u] = %u ", j-1, options[i+j])); 2283 } 2284 DCCP_DEBUG((LOG_INFO, "\n")); 2285 2286 /* 2287 memcpy(&(dp->timestamp_echo), options + i + 2, 4); 2288 memcpy(&(dp->timestamp_elapsed), options + i + 6, 4); 2289 ACK_DEBUG((LOG_INFO, "DATA; echo = %u , elapsed = %u\n", 2290 dp->timestamp_echo, dp->timestamp_elapsed)); 2291 */ 2292 2293 break; 2294 2295 case DCCP_OPT_ACK_VECTOR0: 2296 case DCCP_OPT_ACK_VECTOR1: 2297 case DCCP_OPT_ELAPSEDTIME: 2298 /* Dont do nothing here. Let the CC deal with it */ 2299 break; 2300 2301 default: 2302 DCCP_DEBUG((LOG_INFO, "Got an unknown option, option = %u, size = %u!\n", opt, size)); 2303 break; 2304 2305 } 2306 i += size - 1; 2307 2308 } else { 2309 DCCP_DEBUG((LOG_INFO, "Got a CCID option (%d), do nothing!\n", opt)); 2310 size = options[i+ 1]; 2311 if (size < 3 || size > 10) { 2312 DCCP_DEBUG((LOG_INFO, "Error, option size = %u\n", size)); 2313 return; 2314 } 2315 i += size - 1; 2316 } 2317 } 2318 2319 } 2320 2321 int 2322 dccp_add_feature(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, char *val, u_int8_t val_len) 2323 { 2324 int i; 2325 DCCP_DEBUG((LOG_INFO, "Entering dccp_add_feature, opt = %u, feature = %u, val_len = %u\n", opt, feature, val_len)); 2326 2327 if (DCCP_MAX_OPTIONS > (dp->featlen + val_len + 3)) { 2328 dp->features[dp->featlen] = opt; 2329 dp->features[dp->featlen + 1] = val_len + 3; 2330 dp->features[dp->featlen +2] = feature; 2331 dp->featlen += 3; 2332 for (i = 0; i<val_len; i++) { 2333 dp->features[dp->featlen] = val[i]; 2334 dp->featlen++; 2335 } 2336 } else { 2337 DCCP_DEBUG((LOG_INFO, "No room for more features, featlen = %u\n", dp->featlen)); 2338 return -1; 2339 } 2340 2341 return 0; 2342 } 2343 2344 int 2345 dccp_remove_feature(struct dccpcb *dp, u_int8_t opt, u_int8_t feature) 2346 { 2347 int i = 0, j = 0, k; 2348 u_int8_t t_opt, t_feature, len; 2349 DCCP_DEBUG((LOG_INFO, "Entering dccp_remove_feature, featlen = %u, opt = %u, feature = %u\n", dp->featlen, opt, feature)); 2350 2351 while (i < dp->featlen) { 2352 t_opt = dp->features[i]; 2353 len = dp->features[i+ 1]; 2354 2355 if (i + len > dp->featlen) { 2356 DCCP_DEBUG((LOG_INFO, "Error, len = %u and i(%u) + len > dp->featlen (%u)\n", len, i, dp->featlen)); 2357 return 1; 2358 } 2359 t_feature = dp->features[i+2]; 2360 2361 if (t_opt == opt && t_feature == feature) { 2362 i += len; 2363 } else { 2364 if (i != j) { 2365 for (k = 0; k < len; k++) { 2366 dp->features[j+k] = dp->features[i+k]; 2367 } 2368 } 2369 i += len; 2370 j += len; 2371 } 2372 } 2373 dp->featlen = j; 2374 DCCP_DEBUG((LOG_INFO, "Exiting dccp_remove_feature, featlen = %u\n", dp->featlen)); 2375 return 0; 2376 } 2377 2378 void 2379 dccp_feature_neg(struct dccpcb *dp, u_int8_t opt, u_int8_t feature, u_int8_t val_len, char *val) 2380 { 2381 DCCP_DEBUG((LOG_INFO, "Running dccp_feature_neg, opt = %u, feature = %u len = %u ", opt, feature, val_len)); 2382 2383 switch (feature) { 2384 case DCCP_FEATURE_CC: 2385 DCCP_DEBUG((LOG_INFO, "Got CCID negotiation, opt = %u, val[0] = %u\n", opt, val[0])); 2386 if (opt == DCCP_OPT_CHANGE_R) { 2387 if (val[0] == 2 || val[0] == 3 || val[0] == 0) { 2388 /* try to use preferable CCID */ 2389 int i; 2390 for (i = 1; i < val_len; i ++) if (val[i] == dp->pref_cc) val[0] = dp->pref_cc; 2391 DCCP_DEBUG((LOG_INFO, "Sending DCCP_OPT_CONFIRM_L on CCID %u\n", val[0])); 2392 dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_CC); 2393 dccp_add_feature_option(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_CC , val, 1); 2394 if (dp->cc_in_use[0] < 1) { 2395 dp->cc_state[0] = (*cc_sw[val[0] + 1].cc_send_init)(dp); 2396 dp->cc_in_use[0] = val[0] + 1; 2397 } else { 2398 DCCP_DEBUG((LOG_INFO, "We already have negotiated a CC!!!\n")); 2399 } 2400 } 2401 } else if (opt == DCCP_OPT_CONFIRM_L) { 2402 DCCP_DEBUG((LOG_INFO, "Got DCCP_OPT_CONFIRM_L on CCID %u\n", val[0])); 2403 dccp_remove_feature(dp, DCCP_OPT_CHANGE_R, DCCP_FEATURE_CC); 2404 if (dp->cc_in_use[1] < 1) { 2405 dp->cc_state[1] = (*cc_sw[val[0] + 1].cc_recv_init)(dp); 2406 dp->cc_in_use[1] = val[0] + 1; 2407 DCCP_DEBUG((LOG_INFO, "confirmed cc_in_use[1] = %d\n", dp->cc_in_use[1])); 2408 } else { 2409 DCCP_DEBUG((LOG_INFO, "We already have negotiated a CC!!! (confirm) %d\n", dp->cc_in_use[1])); 2410 } 2411 } 2412 2413 break; 2414 2415 case DCCP_FEATURE_ACKVECTOR: 2416 ACK_DEBUG((LOG_INFO, "Got _Use Ack Vector_\n")); 2417 if (opt == DCCP_OPT_CHANGE_R) { 2418 if (val[0] == 1) { 2419 dccp_use_ackvector(dp); 2420 dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR); 2421 dccp_add_feature_option(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR , val, 1); 2422 } else { 2423 ACK_DEBUG((LOG_INFO, "ERROR. Strange val %u\n", val[0])); 2424 } 2425 } else if (opt == DCCP_OPT_CONFIRM_L) { 2426 dccp_remove_feature(dp, DCCP_OPT_CONFIRM_L, DCCP_FEATURE_ACKVECTOR); 2427 if (val[0] == 1) { 2428 dp->remote_ackvector = 1; 2429 ACK_DEBUG((LOG_INFO,"Remote side confirmed AckVector usage\n")); 2430 } else { 2431 ACK_DEBUG((LOG_INFO, "ERROR. Strange val %u\n", val[0])); 2432 } 2433 } 2434 break; 2435 2436 case DCCP_FEATURE_ACKRATIO: 2437 if (opt == DCCP_OPT_CHANGE_R) { 2438 memcpy(&(dp->ack_ratio), val, 1); 2439 ACK_DEBUG((LOG_INFO, "Feature: Change Ack Ratio to %u\n", dp->ack_ratio)); 2440 } 2441 break; 2442 2443 case DCCP_FEATURE_ECN: 2444 case DCCP_FEATURE_MOBILITY: 2445 default: 2446 /* we should send back empty CONFIRM_L for unknown feature unless it's not mandatory */ 2447 dccp_add_option(dp, DCCP_OPT_CONFIRM_L, NULL, 0); 2448 break; 2449 2450 } 2451 } 2452 2453 #ifdef __FreeBSD__ 2454 static int 2455 dccp_pcblist(SYSCTL_HANDLER_ARGS) 2456 { 2457 2458 int error, i, n, s; 2459 struct inpcb *inp, **inp_list; 2460 inp_gen_t gencnt; 2461 struct xinpgen xig; 2462 2463 /* 2464 * The process of preparing the TCB list is too time-consuming and 2465 * resource-intensive to repeat twice on every request. 2466 */ 2467 if (req->oldptr == 0) { 2468 n = dccpbinfo.ipi_count; 2469 req->oldidx = 2 * (sizeof xig) 2470 + (n + n/8) * sizeof(struct xdccpcb); 2471 return 0; 2472 } 2473 2474 2475 if (req->newptr != 0) 2476 return EPERM; 2477 2478 2479 /* 2480 * OK, now we're committed to doing something. 2481 */ 2482 s = splnet(); 2483 gencnt = dccpbinfo.ipi_gencnt; 2484 n = dccpbinfo.ipi_count; 2485 splx(s); 2486 2487 #if __FreeBSD_version >= 500000 2488 sysctl_wire_old_buffer(req, 2 * (sizeof xig) 2489 + n * sizeof(struct xdccpcb)); 2490 #endif 2491 2492 xig.xig_len = sizeof xig; 2493 xig.xig_count = n; 2494 xig.xig_gen = gencnt; 2495 xig.xig_sogen = so_gencnt; 2496 error = SYSCTL_OUT(req, &xig, sizeof xig); 2497 if (error) 2498 return error; 2499 2500 inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); 2501 if (inp_list == 0) 2502 return ENOMEM; 2503 2504 s = splsoftnet(); 2505 INP_INFO_RLOCK(&dccpbinfo); 2506 2507 for (inp = LIST_FIRST(dccpbinfo.listhead), i = 0; inp && i < n; 2508 inp = LIST_NEXT(inp, inp_list)) { 2509 INP_LOCK(inp); 2510 if (inp->inp_gencnt <= gencnt && 2511 #if __FreeBSD_version >= 500000 2512 cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) 2513 #else 2514 !prison_xinpcb(req->p, inp)) 2515 #endif 2516 inp_list[i++] = inp; 2517 INP_UNLOCK(inp); 2518 } 2519 INP_INFO_RUNLOCK(&dccpbinfo); 2520 splx(s); 2521 n = i; 2522 2523 error = 0; 2524 for (i = 0; i < n; i++) { 2525 inp = inp_list[i]; 2526 INP_LOCK(inp); 2527 2528 if (inp->inp_gencnt <= gencnt) { 2529 struct xdccpcb xd; 2530 vaddr_t inp_ppcb; 2531 xd.xd_len = sizeof xd; 2532 /* XXX should avoid extra copy */ 2533 memcpy(&xd.xd_inp, inp, sizeof *inp); 2534 inp_ppcb = inp->inp_ppcb; 2535 if (inp_ppcb != NULL) 2536 memcpy(&xd.xd_dp, inp_ppcb, sizeof xd.xd_dp); 2537 else 2538 memset((char *) &xd.xd_dp, 0, sizeof xd.xd_dp); 2539 if (inp->inp_socket) 2540 sotoxsocket(inp->inp_socket, &xd.xd_socket); 2541 error = SYSCTL_OUT(req, &xd, sizeof xd); 2542 } 2543 INP_UNLOCK(inp); 2544 } 2545 if (!error) { 2546 /* 2547 * Give the user an updated idea of our state. 2548 * If the generation differs from what we told 2549 * her before, she knows that something happened 2550 * while we were processing this request, and it 2551 * might be necessary to retry. 2552 */ 2553 s = splnet(); 2554 INP_INFO_RLOCK(&dccpbinfo); 2555 xig.xig_gen = dccpbinfo.ipi_gencnt; 2556 xig.xig_sogen = so_gencnt; 2557 xig.xig_count = dccpbinfo.ipi_count; 2558 2559 2560 INP_INFO_RUNLOCK(&dccpbinfo); 2561 splx(s); 2562 error = SYSCTL_OUT(req, &xig, sizeof xig); 2563 } 2564 free(inp_list, M_TEMP); 2565 return error; 2566 } 2567 #endif 2568 2569 #ifdef __FreeBSD__ 2570 SYSCTL_PROC(_net_inet_dccp, DCCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, 2571 dccp_pcblist, "S,xdccpcb", "List of active DCCP sockets"); 2572 #endif 2573 2574 void 2575 dccp_timewait_t(void *dcb) 2576 { 2577 struct dccpcb *dp = dcb; 2578 2579 DCCP_DEBUG((LOG_INFO, "Entering dccp_timewait_t!\n")); 2580 mutex_enter(softnet_lock); 2581 INP_INFO_WLOCK(&dccpbinfo); 2582 INP_LOCK(dp->d_inpcb); 2583 dccp_close(dp); 2584 INP_INFO_WUNLOCK(&dccpbinfo); 2585 mutex_exit(softnet_lock); 2586 } 2587 2588 void 2589 dccp_connect_t(void *dcb) 2590 { 2591 struct dccpcb *dp = dcb; 2592 2593 DCCP_DEBUG((LOG_INFO, "Entering dccp_connect_t!\n")); 2594 mutex_enter(softnet_lock); 2595 INP_INFO_WLOCK(&dccpbinfo); 2596 INP_LOCK(dp->d_inpcb); 2597 dccp_close(dp); 2598 INP_INFO_WUNLOCK(&dccpbinfo); 2599 mutex_exit(softnet_lock); 2600 } 2601 2602 void 2603 dccp_close_t(void *dcb) 2604 { 2605 struct dccpcb *dp = dcb; 2606 2607 DCCP_DEBUG((LOG_INFO, "Entering dccp_close_t!\n")); 2608 mutex_enter(softnet_lock); 2609 INP_INFO_WLOCK(&dccpbinfo); 2610 dp->state = DCCPS_TIME_WAIT; /* HMM */ 2611 if (dp->who == DCCP_SERVER) { 2612 INP_LOCK(dp->d_inpcb); 2613 KERNEL_LOCK(1, NULL); 2614 dccp_output(dp, DCCP_TYPE_RESET + 2); 2615 KERNEL_UNLOCK_ONE(NULL); 2616 dccp_close(dp); 2617 } else { 2618 INP_LOCK(dp->d_inpcb); 2619 dccp_output(dp, DCCP_TYPE_RESET + 2); 2620 /*dp->state = DCCPS_TIME_WAIT; */ 2621 callout_reset(&dp->timewait_timer, DCCP_TIMEWAIT_TIMER, 2622 dccp_timewait_t, dp); 2623 INP_UNLOCK(dp->d_inpcb); 2624 } 2625 INP_INFO_WUNLOCK(&dccpbinfo); 2626 mutex_exit(softnet_lock); 2627 } 2628 2629 void 2630 dccp_retrans_t(void *dcb) 2631 { 2632 struct dccpcb *dp = dcb; 2633 /*struct inpcb *inp;*/ 2634 2635 DCCP_DEBUG((LOG_INFO, "Entering dccp_retrans_t!\n")); 2636 mutex_enter(softnet_lock); 2637 INP_INFO_RLOCK(&dccpbinfo); 2638 /*inp = dp->d_inpcb;*/ 2639 INP_LOCK(inp); 2640 INP_INFO_RUNLOCK(&dccpbinfo); 2641 callout_stop(&dp->retrans_timer); 2642 KERNEL_LOCK(1, NULL); 2643 dccp_output(dp, 0); 2644 KERNEL_UNLOCK_ONE(NULL); 2645 dp->retrans = dp->retrans * 2; 2646 callout_reset(&dp->retrans_timer, dp->retrans, dccp_retrans_t, dp); 2647 INP_UNLOCK(inp); 2648 mutex_exit(softnet_lock); 2649 } 2650 2651 static int 2652 dccp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 2653 { 2654 int error = 0; 2655 int family; 2656 2657 family = so->so_proto->pr_domain->dom_family; 2658 switch (family) { 2659 case PF_INET: 2660 error = in_control(so, cmd, nam, ifp); 2661 break; 2662 #ifdef INET6 2663 case PF_INET6: 2664 error = in6_control(so, cmd, nam, ifp); 2665 break; 2666 #endif 2667 default: 2668 error = EAFNOSUPPORT; 2669 } 2670 return (error); 2671 } 2672 2673 static int 2674 dccp_stat(struct socket *so, struct stat *ub) 2675 { 2676 return 0; 2677 } 2678 2679 static int 2680 dccp_peeraddr(struct socket *so, struct sockaddr *nam) 2681 { 2682 2683 KASSERT(solocked(so)); 2684 KASSERT(sotoinpcb(so) != NULL); 2685 KASSERT(nam != NULL); 2686 2687 inpcb_fetch_peeraddr(sotoinpcb(so), (struct sockaddr_in *)nam); 2688 return 0; 2689 } 2690 2691 static int 2692 dccp_sockaddr(struct socket *so, struct sockaddr *nam) 2693 { 2694 2695 KASSERT(solocked(so)); 2696 KASSERT(sotoinpcb(so) != NULL); 2697 KASSERT(nam != NULL); 2698 2699 inpcb_fetch_sockaddr(sotoinpcb(so), (struct sockaddr_in *)nam); 2700 return 0; 2701 } 2702 2703 static int 2704 dccp_rcvd(struct socket *so, int flags, struct lwp *l) 2705 { 2706 KASSERT(solocked(so)); 2707 2708 return EOPNOTSUPP; 2709 } 2710 2711 static int 2712 dccp_recvoob(struct socket *so, struct mbuf *m, int flags) 2713 { 2714 KASSERT(solocked(so)); 2715 2716 return EOPNOTSUPP; 2717 } 2718 2719 static int 2720 dccp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 2721 { 2722 KASSERT(solocked(so)); 2723 2724 m_freem(m); 2725 m_freem(control); 2726 2727 return EOPNOTSUPP; 2728 } 2729 2730 static int 2731 dccp_purgeif(struct socket *so, struct ifnet *ifp) 2732 { 2733 int s; 2734 2735 s = splsoftnet(); 2736 mutex_enter(softnet_lock); 2737 inpcb_purgeif0(&dccpbtable, ifp); 2738 in_purgeif(ifp); 2739 inpcb_purgeif(&dccpbtable, ifp); 2740 mutex_exit(softnet_lock); 2741 splx(s); 2742 2743 return 0; 2744 } 2745 2746 /****** Ack Vector functions *********/ 2747 2748 /** 2749 * Initialize and allocate mem for Ack Vector 2750 **/ 2751 void 2752 dccp_use_ackvector(struct dccpcb *dp) 2753 { 2754 DCCP_DEBUG((LOG_INFO,"Initializing AckVector\n")); 2755 if (dp->ackvector != 0) { 2756 DCCP_DEBUG((LOG_INFO, "It was already initialized!!!\n")); 2757 return; 2758 } 2759 dp->av_size = DCCP_VECTORSIZE; 2760 /* need 2 bits per entry */ 2761 dp->ackvector = malloc(dp->av_size/4, M_PCB, M_NOWAIT | M_ZERO); 2762 if (dp->ackvector == 0) { 2763 DCCP_DEBUG((LOG_INFO, "Unable to allocate memory for ackvector\n")); 2764 /* What to do now? */ 2765 dp->av_size = 0; 2766 return; 2767 } 2768 memset(dp->ackvector, 0xff, dp->av_size/4); 2769 dp->av_hs = dp->av_ts = 0; 2770 dp->av_hp = dp->ackvector; 2771 } 2772 2773 /** 2774 * Set 'seqnr' as the new head in ackvector 2775 **/ 2776 void 2777 dccp_update_ackvector(struct dccpcb *dp, u_int64_t seqnr) 2778 { 2779 int64_t gap; 2780 u_char *t; 2781 2782 /* Ignore wrapping for now */ 2783 2784 ACK_DEBUG((LOG_INFO,"New head in ackvector: %u\n", seqnr)); 2785 2786 if (dp->av_size == 0) { 2787 ACK_DEBUG((LOG_INFO, "Update: AckVector NOT YET INITIALIZED!!!\n")); 2788 dccp_use_ackvector(dp); 2789 } 2790 2791 if (seqnr > dp->av_hs) { 2792 gap = seqnr - dp->av_hs; 2793 } else { 2794 /* We received obsolete information */ 2795 return; 2796 } 2797 2798 t = dp->av_hp + (gap/4); 2799 if (t >= (dp->ackvector + (dp->av_size/4))) 2800 t -= (dp->av_size / 4); /* ackvector wrapped */ 2801 dp->av_hp = t; 2802 dp->av_hs = seqnr; 2803 } 2804 2805 /** 2806 * We've received a packet. store in local av so it's included in 2807 * next Ack Vector sent 2808 **/ 2809 void 2810 dccp_increment_ackvector(struct dccpcb *dp, u_int64_t seqnr) 2811 { 2812 u_int64_t offset, dc; 2813 int64_t gap; 2814 u_char *t, *n; 2815 2816 DCCP_DEBUG((LOG_INFO, "Entering dccp_increment_ackvecktor %d\n", dp->av_size)); 2817 if (dp->av_size == 0) { 2818 DCCP_DEBUG((LOG_INFO, "Increment: AckVector NOT YET INITIALIZED!!!\n")); 2819 dccp_use_ackvector(dp); 2820 } 2821 2822 if (dp->av_hs == dp->av_ts) { 2823 /* Empty ack vector */ 2824 dp->av_hs = dp->av_ts = seqnr; 2825 } 2826 2827 /* Check for wrapping */ 2828 if (seqnr >= dp->av_hs) { 2829 /* Not wrapped */ 2830 gap = seqnr - dp->av_hs; 2831 } else { 2832 /* Wrapped */ 2833 gap = seqnr + 0x1000000000000LL - dp->av_hs; /* seqnr = 48 bits */ 2834 } 2835 DCCP_DEBUG((LOG_INFO, "dccp_increment_ackvecktor gap=%llu av_size %d\n", gap, dp->av_size)); 2836 2837 if (gap >= dp->av_size) { 2838 /* gap is bigger than ackvector size? baaad */ 2839 /* maybe we should increase the ackvector here */ 2840 DCCP_DEBUG((LOG_INFO, "increment_ackvector error. gap: %llu, av_size: %d, seqnr: %d\n", 2841 gap, dp->av_size, seqnr)); 2842 return; 2843 } 2844 2845 offset = gap % 4; /* hi or low 2 bits to mark */ 2846 t = dp->av_hp + (gap/4); 2847 if (t >= (dp->ackvector + (dp->av_size/4))) 2848 t -= (dp->av_size / 4); /* ackvector wrapped */ 2849 2850 *t = *t & (~(0x03 << (offset *2))); /* turn off bits, 00 is rcvd, 11 is missing */ 2851 2852 dp->av_ts = seqnr + 1; 2853 if (dp->av_ts == 0x1000000000000LL) 2854 dp->av_ts = 0; 2855 2856 if (gap > (dp->av_size - 128)) { 2857 n = malloc(dp->av_size/2, M_PCB, M_NOWAIT | M_ZERO); /* old size * 2 */ 2858 memset (n + dp->av_size / 4, 0xff, dp->av_size / 4); /* new half all missing */ 2859 dc = (dp->ackvector + (dp->av_size/4)) - dp->av_hp; 2860 memcpy (n, dp->av_hp, dc); /* tail to end */ 2861 memcpy (n+dc, dp->ackvector, dp->av_hp - dp->ackvector); /* start to tail */ 2862 dp->av_size = dp->av_size * 2; /* counted in items, so it';s a doubling */ 2863 free (dp->ackvector, M_PCB); 2864 dp->av_hp = dp->ackvector = n; 2865 } 2866 } 2867 2868 /** 2869 * Generates the ack vector to send in outgoing packet. 2870 * These are backwards (first packet in ack vector is packet indicated by Ack Number, 2871 * subsequent are older packets). 2872 **/ 2873 2874 u_int16_t 2875 dccp_generate_ackvector(struct dccpcb *dp, u_char *buf) 2876 { 2877 int64_t j; 2878 u_int64_t i; 2879 u_int16_t cnt, oldlen, bufsize; 2880 u_char oldstate, st; 2881 2882 bufsize = 16; 2883 cnt = 0; 2884 2885 oldstate = 0x04; /* bad value */ 2886 oldlen = 0; 2887 2888 if (dp->av_size == 0) { 2889 ACK_DEBUG((LOG_INFO, "Generate: AckVector NOT YET INITIALIZED!!!\n")); 2890 return 0; 2891 } 2892 2893 if (dp->seq_rcv > dp->av_ts) { 2894 /* AckNum is beyond our av-list , so we'll start with some 2895 * 0x3 (Packet not yet received) */ 2896 j = dp->seq_rcv - dp->av_ts -1; 2897 do { 2898 /* state | length */ 2899 oldstate = 0x03; 2900 if (j > 63) 2901 oldlen = 63; 2902 else 2903 oldlen = j; 2904 2905 buf[cnt] = (0x03 << 6) | oldlen; 2906 cnt++; 2907 if (cnt == bufsize) { 2908 /* I've skipped the realloc bshit */ 2909 /* PANIC */ 2910 } 2911 j-=63; 2912 } while (j > 0); 2913 } 2914 2915 /* Ok now we're at dp->av_ts (unless AckNum is lower) */ 2916 i = (dp->seq_rcv < dp->av_ts) ? dp->seq_rcv : dp->av_ts; 2917 st = dccp_ackvector_state(dp, i); 2918 2919 if (st == oldstate) { 2920 cnt--; 2921 oldlen++; 2922 } else { 2923 oldlen = 0; 2924 oldstate = st; 2925 } 2926 2927 if (dp->av_ts > dp->av_hs) { 2928 do { 2929 i--; 2930 st = dccp_ackvector_state(dp, i); 2931 if (st == oldstate && oldlen < 64) { 2932 oldlen++; 2933 } else { 2934 buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2935 cnt++; 2936 oldlen = 0; 2937 oldstate = st; 2938 if (cnt == bufsize) { 2939 /* PANIC */ 2940 } 2941 } 2942 2943 } while (i > dp->av_hs); 2944 } else { 2945 /* It's wrapped */ 2946 do { 2947 i--; 2948 st = dccp_ackvector_state(dp, i); 2949 if (st == oldstate && oldlen < 64) { 2950 oldlen++; 2951 } else { 2952 buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2953 cnt++; 2954 oldlen = 0; 2955 oldstate = st; 2956 if (cnt == bufsize) { 2957 /* PANIC */ 2958 } 2959 } 2960 2961 } while (i > 0); 2962 i = 0x1000000; 2963 do { 2964 i--; 2965 st = dccp_ackvector_state(dp, i); 2966 if (st == oldstate && oldlen < 64) { 2967 oldlen++; 2968 } else { 2969 buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2970 cnt++; 2971 oldlen = 0; 2972 oldstate = st; 2973 if (cnt == bufsize) { 2974 /* PANIC */ 2975 } 2976 } 2977 } while (i > dp->av_hs); 2978 } 2979 2980 /* add the last one */ 2981 buf[cnt] = (oldstate << 6) | (oldlen & 0x3f); 2982 cnt++; 2983 2984 return cnt; 2985 } 2986 2987 u_char 2988 dccp_ackvector_state(struct dccpcb *dp, u_int64_t seqnr) 2989 { 2990 u_int64_t gap, offset; 2991 u_char *t; 2992 2993 /* Check for wrapping */ 2994 if (seqnr >= dp->av_hs) { 2995 /* Not wrapped */ 2996 gap = seqnr - dp->av_hs; 2997 } else { 2998 /* Wrapped */ 2999 gap = seqnr + 0x1000000000000LL - dp->av_hs; /* seq nr = 48 bits */ 3000 } 3001 3002 if (gap >= dp->av_size) { 3003 /* gap is bigger than ackvector size? baaad */ 3004 return 0x03; 3005 } 3006 3007 offset = gap % 4 *2; 3008 t = dp->av_hp + (gap/4); 3009 if (t >= (dp->ackvector + (dp->av_size/4))) 3010 t -= (dp->av_size / 4); /* wrapped */ 3011 3012 return ((*t & (0x03 << offset)) >> offset); 3013 } 3014 3015 /****** End of Ack Vector functions *********/ 3016 3017 /* No cc functions */ 3018 void * 3019 dccp_nocc_init(struct dccpcb *pcb) 3020 { 3021 return (void*) 1; 3022 } 3023 3024 void 3025 dccp_nocc_free(void *ccb) 3026 { 3027 } 3028 3029 int 3030 dccp_nocc_send_packet(void *ccb, long size) 3031 { 3032 return 1; 3033 } 3034 3035 void 3036 dccp_nocc_send_packet_sent(void *ccb, int moreToSend, long size) 3037 { 3038 } 3039 3040 void 3041 dccp_nocc_packet_recv(void *ccb, char* options ,int optlen) 3042 { 3043 } 3044 3045 void 3046 dccp_log(int level, const char *format, ...) 3047 { 3048 va_list ap; 3049 3050 va_start(ap, format); 3051 vprintf(format, ap); 3052 va_end(ap); 3053 return; 3054 } 3055 3056 /* 3057 * Sysctl for dccp variables. 3058 */ 3059 SYSCTL_SETUP(sysctl_net_inet_dccp_setup, "sysctl net.inet.dccp subtree setup") 3060 { 3061 3062 sysctl_createv(clog, 0, NULL, NULL, 3063 CTLFLAG_PERMANENT, 3064 CTLTYPE_NODE, "net", NULL, 3065 NULL, 0, NULL, 0, 3066 CTL_NET, CTL_EOL); 3067 3068 sysctl_createv(clog, 0, NULL, NULL, 3069 CTLFLAG_PERMANENT, 3070 CTLTYPE_NODE, "inet", NULL, 3071 NULL, 0, NULL, 0, 3072 CTL_NET, PF_INET, CTL_EOL); 3073 3074 sysctl_createv(clog, 0, NULL, NULL, 3075 CTLFLAG_PERMANENT, 3076 CTLTYPE_NODE, "dccp", 3077 SYSCTL_DESCR("DCCPv4 related settings"), 3078 NULL, 0, NULL, 0, 3079 CTL_NET, PF_INET, IPPROTO_DCCP, CTL_EOL); 3080 3081 sysctl_createv(clog, 0, NULL, NULL, 3082 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3083 CTLTYPE_INT, "dccp_log_in_vain", 3084 SYSCTL_DESCR("log all connection attempt"), 3085 NULL, 0, &dccp_log_in_vain, 0, 3086 CTL_NET, PF_INET, IPPROTO_DCCP, DCCPCTL_LOGINVAIN, 3087 CTL_EOL); 3088 3089 sysctl_createv(clog, 0, NULL, NULL, 3090 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3091 CTLTYPE_INT, "do_feature_nego", 3092 SYSCTL_DESCR("enable feature negotiation"), 3093 NULL, 0, &dccp_do_feature_nego, 0, 3094 CTL_NET, PF_INET, IPPROTO_DCCP, DCCPCTL_DOFEATURENEGO, 3095 CTL_EOL); 3096 } 3097 3098 PR_WRAP_USRREQS(dccp) 3099 #define dccp_attach dccp_attach_wrapper 3100 #define dccp_detach dccp_detach_wrapper 3101 #define dccp_accept dccp_accept_wrapper 3102 #define dccp_bind dccp_bind_wrapper 3103 #define dccp_listen dccp_listen_wrapper 3104 #define dccp_connect dccp_connect_wrapper 3105 #define dccp_connect2 dccp_connect2_wrapper 3106 #define dccp_disconnect dccp_disconnect_wrapper 3107 #define dccp_shutdown dccp_shutdown_wrapper 3108 #define dccp_abort dccp_abort_wrapper 3109 #define dccp_ioctl dccp_ioctl_wrapper 3110 #define dccp_stat dccp_stat_wrapper 3111 #define dccp_peeraddr dccp_peeraddr_wrapper 3112 #define dccp_sockaddr dccp_sockaddr_wrapper 3113 #define dccp_rcvd dccp_rcvd_wrapper 3114 #define dccp_recvoob dccp_recvoob_wrapper 3115 #define dccp_send dccp_send_wrapper 3116 #define dccp_sendoob dccp_sendoob_wrapper 3117 #define dccp_purgeif dccp_purgeif_wrapper 3118 3119 const struct pr_usrreqs dccp_usrreqs = { 3120 .pr_attach = dccp_attach, 3121 .pr_detach = dccp_detach, 3122 .pr_accept = dccp_accept, 3123 .pr_bind = dccp_bind, 3124 .pr_listen = dccp_listen, 3125 .pr_connect = dccp_connect, 3126 .pr_connect2 = dccp_connect2, 3127 .pr_disconnect = dccp_disconnect, 3128 .pr_shutdown = dccp_shutdown, 3129 .pr_abort = dccp_abort, 3130 .pr_ioctl = dccp_ioctl, 3131 .pr_stat = dccp_stat, 3132 .pr_peeraddr = dccp_peeraddr, 3133 .pr_sockaddr = dccp_sockaddr, 3134 .pr_rcvd = dccp_rcvd, 3135 .pr_recvoob = dccp_recvoob, 3136 .pr_send = dccp_send, 3137 .pr_sendoob = dccp_sendoob, 3138 .pr_purgeif = dccp_purgeif, 3139 }; 3140