1 /* 2 * ng_ksocket.c 3 */ 4 5 /*- 6 * Copyright (c) 1996-1999 Whistle Communications, Inc. 7 * All rights reserved. 8 * 9 * Subject to the following obligations and disclaimer of warranty, use and 10 * redistribution of this software, in source or object code forms, with or 11 * without modifications are expressly permitted by Whistle Communications; 12 * provided, however, that: 13 * 1. Any and all reproductions of the source or object code must include the 14 * copyright notice above and the following disclaimer of warranties; and 15 * 2. No rights are granted, in any manner or form, to use Whistle 16 * Communications, Inc. trademarks, including the mark "WHISTLE 17 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18 * such appears in the above copyright notice or in the software. 19 * 20 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 21 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 25 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 26 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 27 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 28 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36 * OF SUCH DAMAGE. 37 * 38 * Author: Archie Cobbs <archie@freebsd.org> 39 * 40 * $FreeBSD: src/sys/netgraph/ng_ksocket.c,v 1.61 2008/03/07 21:12:56 mav Exp $ 41 * $Whistle: ng_ksocket.c,v 1.1 1999/11/16 20:04:40 archie Exp $ 42 */ 43 44 /* 45 * Kernel socket node type. This node type is basically a kernel-mode 46 * version of a socket... kindof like the reverse of the socket node type. 47 */ 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/mbuf.h> 53 #include <sys/proc.h> 54 #include <sys/malloc.h> 55 #include <sys/ctype.h> 56 #include <sys/protosw.h> 57 #include <sys/errno.h> 58 #include <sys/fcntl.h> 59 #include <sys/socket.h> 60 #include <sys/socketops.h> 61 #include <sys/socketvar.h> 62 #include <sys/socketvar2.h> 63 #include <sys/thread2.h> 64 #include <sys/uio.h> 65 #include <sys/un.h> 66 67 #include <netgraph7/ng_message.h> 68 #include <netgraph7/netgraph.h> 69 #include <netgraph7/ng_parse.h> 70 #include "ng_ksocket.h" 71 72 #include <netinet/in.h> 73 74 #ifdef NG_SEPARATE_MALLOC 75 MALLOC_DEFINE(M_NETGRAPH_KSOCKET, "netgraph_ksock", "netgraph ksock node "); 76 #else 77 #define M_NETGRAPH_KSOCKET M_NETGRAPH 78 #endif 79 80 #define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0)) 81 #define SADATA_OFFSET (OFFSETOF(struct sockaddr, sa_data)) 82 83 /* Node private data */ 84 struct ng_ksocket_private { 85 node_p node; 86 hook_p hook; 87 struct socket *so; 88 int fn_sent; /* FN call on incoming event was sent */ 89 LIST_HEAD(, ng_ksocket_private) embryos; 90 LIST_ENTRY(ng_ksocket_private) siblings; 91 u_int32_t flags; 92 u_int32_t response_token; 93 ng_ID_t response_addr; 94 }; 95 typedef struct ng_ksocket_private *priv_p; 96 97 /* Flags for priv_p */ 98 #define KSF_CONNECTING 0x00000001 /* Waiting for connection complete */ 99 #define KSF_ACCEPTING 0x00000002 /* Waiting for accept complete */ 100 #define KSF_EOFSEEN 0x00000004 /* Have sent 0-length EOF mbuf */ 101 #define KSF_CLONED 0x00000008 /* Cloned from an accepting socket */ 102 #define KSF_EMBRYONIC 0x00000010 /* Cloned node with no hooks yet */ 103 104 /* Netgraph node methods */ 105 static ng_constructor_t ng_ksocket_constructor; 106 static ng_rcvmsg_t ng_ksocket_rcvmsg; 107 static ng_shutdown_t ng_ksocket_shutdown; 108 static ng_newhook_t ng_ksocket_newhook; 109 static ng_rcvdata_t ng_ksocket_rcvdata; 110 static ng_connect_t ng_ksocket_connect; 111 static ng_disconnect_t ng_ksocket_disconnect; 112 113 /* Alias structure */ 114 struct ng_ksocket_alias { 115 const char *name; 116 const int value; 117 const int family; 118 }; 119 120 /* Protocol family aliases */ 121 static const struct ng_ksocket_alias ng_ksocket_families[] = { 122 { "local", PF_LOCAL }, 123 { "inet", PF_INET }, 124 { "inet6", PF_INET6 }, 125 { "atm", PF_ATM }, 126 { NULL, -1 }, 127 }; 128 129 /* Socket type aliases */ 130 static const struct ng_ksocket_alias ng_ksocket_types[] = { 131 { "stream", SOCK_STREAM }, 132 { "dgram", SOCK_DGRAM }, 133 { "raw", SOCK_RAW }, 134 { "rdm", SOCK_RDM }, 135 { "seqpacket", SOCK_SEQPACKET }, 136 { NULL, -1 }, 137 }; 138 139 /* Protocol aliases */ 140 static const struct ng_ksocket_alias ng_ksocket_protos[] = { 141 { "ip", IPPROTO_IP, PF_INET }, 142 { "raw", IPPROTO_RAW, PF_INET }, 143 { "icmp", IPPROTO_ICMP, PF_INET }, 144 { "igmp", IPPROTO_IGMP, PF_INET }, 145 { "tcp", IPPROTO_TCP, PF_INET }, 146 { "udp", IPPROTO_UDP, PF_INET }, 147 { "gre", IPPROTO_GRE, PF_INET }, 148 { "esp", IPPROTO_ESP, PF_INET }, 149 { "ah", IPPROTO_AH, PF_INET }, 150 { "swipe", IPPROTO_SWIPE, PF_INET }, 151 { "encap", IPPROTO_ENCAP, PF_INET }, 152 { "divert", IPPROTO_DIVERT, PF_INET }, 153 { "pim", IPPROTO_PIM, PF_INET }, 154 { NULL, -1 }, 155 }; 156 157 /* Helper functions */ 158 static int ng_ksocket_check_accept(priv_p); 159 static void ng_ksocket_finish_accept(priv_p); 160 static void ng_ksocket_incoming(struct socket *so, void *arg, int waitflag); 161 static int ng_ksocket_parse(const struct ng_ksocket_alias *aliases, 162 const char *s, int family); 163 static void ng_ksocket_incoming2(node_p node, hook_p hook, 164 void *arg1, int arg2); 165 166 /************************************************************************ 167 STRUCT SOCKADDR PARSE TYPE 168 ************************************************************************/ 169 170 /* Get the length of the data portion of a generic struct sockaddr */ 171 static int 172 ng_parse_generic_sockdata_getLength(const struct ng_parse_type *type, 173 const u_char *start, const u_char *buf) 174 { 175 const struct sockaddr *sa; 176 177 sa = (const struct sockaddr *)(buf - SADATA_OFFSET); 178 return (sa->sa_len < SADATA_OFFSET) ? 0 : sa->sa_len - SADATA_OFFSET; 179 } 180 181 /* Type for the variable length data portion of a generic struct sockaddr */ 182 static const struct ng_parse_type ng_ksocket_generic_sockdata_type = { 183 &ng_parse_bytearray_type, 184 &ng_parse_generic_sockdata_getLength 185 }; 186 187 /* Type for a generic struct sockaddr */ 188 static const struct ng_parse_struct_field 189 ng_parse_generic_sockaddr_type_fields[] = { 190 { "len", &ng_parse_uint8_type }, 191 { "family", &ng_parse_uint8_type }, 192 { "data", &ng_ksocket_generic_sockdata_type }, 193 { NULL } 194 }; 195 static const struct ng_parse_type ng_ksocket_generic_sockaddr_type = { 196 &ng_parse_struct_type, 197 &ng_parse_generic_sockaddr_type_fields 198 }; 199 200 /* Convert a struct sockaddr from ASCII to binary. If its a protocol 201 family that we specially handle, do that, otherwise defer to the 202 generic parse type ng_ksocket_generic_sockaddr_type. */ 203 static int 204 ng_ksocket_sockaddr_parse(const struct ng_parse_type *type, 205 const char *s, int *off, const u_char *const start, 206 u_char *const buf, int *buflen) 207 { 208 struct sockaddr *const sa = (struct sockaddr *)buf; 209 enum ng_parse_token tok; 210 char fambuf[32]; 211 int family, len; 212 char *t; 213 214 /* If next token is a left curly brace, use generic parse type */ 215 if ((tok = ng_parse_get_token(s, off, &len)) == T_LBRACE) { 216 return (*ng_ksocket_generic_sockaddr_type.supertype->parse) 217 (&ng_ksocket_generic_sockaddr_type, 218 s, off, start, buf, buflen); 219 } 220 221 /* Get socket address family followed by a slash */ 222 while (isspace(s[*off])) 223 (*off)++; 224 if ((t = index(s + *off, '/')) == NULL) 225 return (EINVAL); 226 if ((len = t - (s + *off)) > sizeof(fambuf) - 1) 227 return (EINVAL); 228 strncpy(fambuf, s + *off, len); 229 fambuf[len] = '\0'; 230 *off += len + 1; 231 if ((family = ng_ksocket_parse(ng_ksocket_families, fambuf, 0)) == -1) 232 return (EINVAL); 233 234 /* Set family */ 235 if (*buflen < SADATA_OFFSET) 236 return (ERANGE); 237 sa->sa_family = family; 238 239 /* Set family-specific data and length */ 240 switch (sa->sa_family) { 241 case PF_LOCAL: /* Get pathname */ 242 { 243 const int pathoff = OFFSETOF(struct sockaddr_un, sun_path); 244 struct sockaddr_un *const sun = (struct sockaddr_un *)sa; 245 int toklen, pathlen; 246 char *path; 247 248 if ((path = ng_get_string_token(s, off, &toklen, NULL)) == NULL) 249 return (EINVAL); 250 pathlen = strlen(path); 251 if (pathlen > SOCK_MAXADDRLEN) { 252 kfree(path, M_NETGRAPH_KSOCKET); 253 return (E2BIG); 254 } 255 if (*buflen < pathoff + pathlen) { 256 kfree(path, M_NETGRAPH_KSOCKET); 257 return (ERANGE); 258 } 259 *off += toklen; 260 bcopy(path, sun->sun_path, pathlen); 261 sun->sun_len = pathoff + pathlen; 262 kfree(path, M_NETGRAPH_KSOCKET); 263 break; 264 } 265 266 case PF_INET: /* Get an IP address with optional port */ 267 { 268 struct sockaddr_in *const sin = (struct sockaddr_in *)sa; 269 int i; 270 271 /* Parse this: <ipaddress>[:port] */ 272 for (i = 0; i < 4; i++) { 273 u_long val; 274 char *eptr; 275 276 val = strtoul(s + *off, &eptr, 10); 277 if (val > 0xff || eptr == s + *off) 278 return (EINVAL); 279 *off += (eptr - (s + *off)); 280 ((u_char *)&sin->sin_addr)[i] = (u_char)val; 281 if (i < 3) { 282 if (s[*off] != '.') 283 return (EINVAL); 284 (*off)++; 285 } else if (s[*off] == ':') { 286 (*off)++; 287 val = strtoul(s + *off, &eptr, 10); 288 if (val > 0xffff || eptr == s + *off) 289 return (EINVAL); 290 *off += (eptr - (s + *off)); 291 sin->sin_port = htons(val); 292 } else 293 sin->sin_port = 0; 294 } 295 bzero(&sin->sin_zero, sizeof(sin->sin_zero)); 296 sin->sin_len = sizeof(*sin); 297 break; 298 } 299 300 #if 0 301 case PF_INET6: 302 #endif 303 304 default: 305 return (EINVAL); 306 } 307 308 /* Done */ 309 *buflen = sa->sa_len; 310 return (0); 311 } 312 313 /* Convert a struct sockaddr from binary to ASCII */ 314 static int 315 ng_ksocket_sockaddr_unparse(const struct ng_parse_type *type, 316 const u_char *data, int *off, char *cbuf, int cbuflen) 317 { 318 const struct sockaddr *sa = (const struct sockaddr *)(data + *off); 319 int slen = 0; 320 321 /* Output socket address, either in special or generic format */ 322 switch (sa->sa_family) { 323 case PF_LOCAL: 324 { 325 const int pathoff = OFFSETOF(struct sockaddr_un, sun_path); 326 const struct sockaddr_un *sun = (const struct sockaddr_un *)sa; 327 const int pathlen = sun->sun_len - pathoff; 328 char pathbuf[SOCK_MAXADDRLEN + 1]; 329 char *pathtoken; 330 331 bcopy(sun->sun_path, pathbuf, pathlen); 332 if ((pathtoken = ng_encode_string(pathbuf, pathlen)) == NULL) 333 return (ENOMEM); 334 slen += ksnprintf(cbuf, cbuflen, "local/%s", pathtoken); 335 kfree(pathtoken, M_NETGRAPH_KSOCKET); 336 if (slen >= cbuflen) 337 return (ERANGE); 338 *off += sun->sun_len; 339 return (0); 340 } 341 342 case PF_INET: 343 { 344 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; 345 346 slen += ksnprintf(cbuf, cbuflen, "inet/%d.%d.%d.%d", 347 ((const u_char *)&sin->sin_addr)[0], 348 ((const u_char *)&sin->sin_addr)[1], 349 ((const u_char *)&sin->sin_addr)[2], 350 ((const u_char *)&sin->sin_addr)[3]); 351 if (sin->sin_port != 0) { 352 slen += ksnprintf(cbuf + strlen(cbuf), 353 cbuflen - strlen(cbuf), ":%d", 354 (u_int)ntohs(sin->sin_port)); 355 } 356 if (slen >= cbuflen) 357 return (ERANGE); 358 *off += sizeof(*sin); 359 return(0); 360 } 361 362 #if 0 363 case PF_INET6: 364 #endif 365 366 default: 367 return (*ng_ksocket_generic_sockaddr_type.supertype->unparse) 368 (&ng_ksocket_generic_sockaddr_type, 369 data, off, cbuf, cbuflen); 370 } 371 } 372 373 /* Parse type for struct sockaddr */ 374 static const struct ng_parse_type ng_ksocket_sockaddr_type = { 375 NULL, 376 NULL, 377 NULL, 378 &ng_ksocket_sockaddr_parse, 379 &ng_ksocket_sockaddr_unparse, 380 NULL /* no such thing as a default struct sockaddr */ 381 }; 382 383 /************************************************************************ 384 STRUCT NG_KSOCKET_SOCKOPT PARSE TYPE 385 ************************************************************************/ 386 387 /* Get length of the struct ng_ksocket_sockopt value field, which is the 388 just the excess of the message argument portion over the length of 389 the struct ng_ksocket_sockopt. */ 390 static int 391 ng_parse_sockoptval_getLength(const struct ng_parse_type *type, 392 const u_char *start, const u_char *buf) 393 { 394 static const int offset = OFFSETOF(struct ng_ksocket_sockopt, value); 395 const struct ng_ksocket_sockopt *sopt; 396 const struct ng_mesg *msg; 397 398 sopt = (const struct ng_ksocket_sockopt *)(buf - offset); 399 msg = (const struct ng_mesg *)((const u_char *)sopt - sizeof(*msg)); 400 return msg->header.arglen - sizeof(*sopt); 401 } 402 403 /* Parse type for the option value part of a struct ng_ksocket_sockopt 404 XXX Eventually, we should handle the different socket options specially. 405 XXX This would avoid byte order problems, eg an integer value of 1 is 406 XXX going to be "[1]" for little endian or "[3=1]" for big endian. */ 407 static const struct ng_parse_type ng_ksocket_sockoptval_type = { 408 &ng_parse_bytearray_type, 409 &ng_parse_sockoptval_getLength 410 }; 411 412 /* Parse type for struct ng_ksocket_sockopt */ 413 static const struct ng_parse_struct_field ng_ksocket_sockopt_type_fields[] 414 = NG_KSOCKET_SOCKOPT_INFO(&ng_ksocket_sockoptval_type); 415 static const struct ng_parse_type ng_ksocket_sockopt_type = { 416 &ng_parse_struct_type, 417 &ng_ksocket_sockopt_type_fields 418 }; 419 420 /* Parse type for struct ng_ksocket_accept */ 421 static const struct ng_parse_struct_field ng_ksocket_accept_type_fields[] 422 = NGM_KSOCKET_ACCEPT_INFO; 423 static const struct ng_parse_type ng_ksocket_accept_type = { 424 &ng_parse_struct_type, 425 &ng_ksocket_accept_type_fields 426 }; 427 428 /* List of commands and how to convert arguments to/from ASCII */ 429 static const struct ng_cmdlist ng_ksocket_cmds[] = { 430 { 431 NGM_KSOCKET_COOKIE, 432 NGM_KSOCKET_BIND, 433 "bind", 434 &ng_ksocket_sockaddr_type, 435 NULL 436 }, 437 { 438 NGM_KSOCKET_COOKIE, 439 NGM_KSOCKET_LISTEN, 440 "listen", 441 &ng_parse_int32_type, 442 NULL 443 }, 444 { 445 NGM_KSOCKET_COOKIE, 446 NGM_KSOCKET_ACCEPT, 447 "accept", 448 NULL, 449 &ng_ksocket_accept_type 450 }, 451 { 452 NGM_KSOCKET_COOKIE, 453 NGM_KSOCKET_CONNECT, 454 "connect", 455 &ng_ksocket_sockaddr_type, 456 &ng_parse_int32_type 457 }, 458 { 459 NGM_KSOCKET_COOKIE, 460 NGM_KSOCKET_GETNAME, 461 "getname", 462 NULL, 463 &ng_ksocket_sockaddr_type 464 }, 465 { 466 NGM_KSOCKET_COOKIE, 467 NGM_KSOCKET_GETPEERNAME, 468 "getpeername", 469 NULL, 470 &ng_ksocket_sockaddr_type 471 }, 472 { 473 NGM_KSOCKET_COOKIE, 474 NGM_KSOCKET_SETOPT, 475 "setopt", 476 &ng_ksocket_sockopt_type, 477 NULL 478 }, 479 { 480 NGM_KSOCKET_COOKIE, 481 NGM_KSOCKET_GETOPT, 482 "getopt", 483 &ng_ksocket_sockopt_type, 484 &ng_ksocket_sockopt_type 485 }, 486 { 0 } 487 }; 488 489 /* Node type descriptor */ 490 static struct ng_type ng_ksocket_typestruct = { 491 .version = NG_ABI_VERSION, 492 .name = NG_KSOCKET_NODE_TYPE, 493 .constructor = ng_ksocket_constructor, 494 .rcvmsg = ng_ksocket_rcvmsg, 495 .shutdown = ng_ksocket_shutdown, 496 .newhook = ng_ksocket_newhook, 497 .connect = ng_ksocket_connect, 498 .rcvdata = ng_ksocket_rcvdata, 499 .disconnect = ng_ksocket_disconnect, 500 .cmdlist = ng_ksocket_cmds, 501 }; 502 NETGRAPH_INIT(ksocket, &ng_ksocket_typestruct); 503 504 #define ERROUT(x) do { error = (x); goto done; } while (0) 505 506 /************************************************************************ 507 NETGRAPH NODE STUFF 508 ************************************************************************/ 509 510 /* 511 * Node type constructor 512 * The NODE part is assumed to be all set up. 513 * There is already a reference to the node for us. 514 */ 515 static int 516 ng_ksocket_constructor(node_p node) 517 { 518 priv_p priv; 519 520 /* Allocate private structure */ 521 priv = kmalloc(sizeof(*priv), M_NETGRAPH, 522 M_WAITOK | M_NULLOK | M_ZERO); 523 if (priv == NULL) 524 return (ENOMEM); 525 526 LIST_INIT(&priv->embryos); 527 /* cross link them */ 528 priv->node = node; 529 NG_NODE_SET_PRIVATE(node, priv); 530 531 /* Done */ 532 return (0); 533 } 534 535 /* 536 * Give our OK for a hook to be added. The hook name is of the 537 * form "<family>/<type>/<proto>" where the three components may 538 * be decimal numbers or else aliases from the above lists. 539 * 540 * Connecting a hook amounts to opening the socket. Disconnecting 541 * the hook closes the socket and destroys the node as well. 542 */ 543 static int 544 ng_ksocket_newhook(node_p node, hook_p hook, const char *name0) 545 { 546 struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ 547 const priv_p priv = NG_NODE_PRIVATE(node); 548 char *s1, *s2, name[NG_HOOKSIZ]; 549 int family, type, protocol, error; 550 551 /* Check if we're already connected */ 552 if (priv->hook != NULL) 553 return (EISCONN); 554 555 if (priv->flags & KSF_CLONED) { 556 if (priv->flags & KSF_EMBRYONIC) { 557 /* Remove ourselves from our parent's embryo list */ 558 LIST_REMOVE(priv, siblings); 559 priv->flags &= ~KSF_EMBRYONIC; 560 } 561 } else { 562 /* Extract family, type, and protocol from hook name */ 563 ksnprintf(name, sizeof(name), "%s", name0); 564 s1 = name; 565 if ((s2 = index(s1, '/')) == NULL) 566 return (EINVAL); 567 *s2++ = '\0'; 568 family = ng_ksocket_parse(ng_ksocket_families, s1, 0); 569 if (family == -1) 570 return (EINVAL); 571 s1 = s2; 572 if ((s2 = index(s1, '/')) == NULL) 573 return (EINVAL); 574 *s2++ = '\0'; 575 type = ng_ksocket_parse(ng_ksocket_types, s1, 0); 576 if (type == -1) 577 return (EINVAL); 578 s1 = s2; 579 protocol = ng_ksocket_parse(ng_ksocket_protos, s1, family); 580 if (protocol == -1) 581 return (EINVAL); 582 583 /* Create the socket */ 584 error = socreate(family, &priv->so, type, protocol, td); 585 if (error != 0) 586 return (error); 587 588 /* XXX call soreserve() ? */ 589 590 } 591 592 /* OK */ 593 priv->hook = hook; 594 595 /* 596 * In case of misconfigured routing a packet may reenter 597 * ksocket node recursively. Decouple stack to avoid possible 598 * panics about sleeping with locks held. 599 */ 600 NG_HOOK_FORCE_QUEUE(hook); 601 602 return(0); 603 } 604 605 static int 606 ng_ksocket_connect(hook_p hook) 607 { 608 node_p node = NG_HOOK_NODE(hook); 609 const priv_p priv = NG_NODE_PRIVATE(node); 610 struct socket *const so = priv->so; 611 612 /* Add our hook for incoming data and other events */ 613 priv->so->so_upcallarg = (caddr_t)node; 614 priv->so->so_upcall = ng_ksocket_incoming; 615 atomic_set_int(&priv->so->so_rcv.ssb_flags, SSB_UPCALL); 616 atomic_set_int(&priv->so->so_snd.ssb_flags, SSB_UPCALL); 617 /* 618 * --Original comment-- 619 * On a cloned socket we may have already received one or more 620 * upcalls which we couldn't handle without a hook. Handle 621 * those now. 622 * We cannot call the upcall function directly 623 * from here, because until this function has returned our 624 * hook isn't connected. 625 * 626 * ---meta comment for -current --- 627 * XXX This is dubius. 628 * Upcalls between the time that the hook was 629 * first created and now (on another processesor) will 630 * be earlier on the queue than the request to finalise the hook. 631 * By the time the hook is finalised, 632 * The queued upcalls will have happenned and the code 633 * will have discarded them because of a lack of a hook. 634 * (socket not open). 635 * 636 * This is a bad byproduct of the complicated way in which hooks 637 * are now created (3 daisy chained async events). 638 * 639 * Since we are a netgraph operation 640 * We know that we hold a lock on this node. This forces the 641 * request we make below to be queued rather than implemented 642 * immediatly which will cause the upcall function to be called a bit 643 * later. 644 * However, as we will run any waiting queued operations immediatly 645 * after doing this one, if we have not finalised the other end 646 * of the hook, those queued operations will fail. 647 */ 648 if (priv->flags & KSF_CLONED) { 649 ng_send_fn(node, NULL, &ng_ksocket_incoming2, so, M_WAITOK | M_NULLOK); 650 } 651 652 return (0); 653 } 654 655 /* 656 * Receive a control message 657 */ 658 static int 659 ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook) 660 { 661 struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ 662 const priv_p priv = NG_NODE_PRIVATE(node); 663 struct socket *const so = priv->so; 664 struct ng_mesg *resp = NULL; 665 int error = 0; 666 struct ng_mesg *msg; 667 668 NGI_GET_MSG(item, msg); 669 switch (msg->header.typecookie) { 670 case NGM_KSOCKET_COOKIE: 671 switch (msg->header.cmd) { 672 case NGM_KSOCKET_BIND: 673 { 674 struct sockaddr *const sa 675 = (struct sockaddr *)msg->data; 676 677 /* Sanity check */ 678 if (msg->header.arglen < SADATA_OFFSET 679 || msg->header.arglen < sa->sa_len) 680 ERROUT(EINVAL); 681 if (so == NULL) 682 ERROUT(ENXIO); 683 684 /* Bind */ 685 error = sobind(so, sa, td); 686 break; 687 } 688 case NGM_KSOCKET_LISTEN: 689 { 690 /* Sanity check */ 691 if (msg->header.arglen != sizeof(int32_t)) 692 ERROUT(EINVAL); 693 if (so == NULL) 694 ERROUT(ENXIO); 695 696 /* Listen */ 697 error = solisten(so, *((int32_t *)msg->data), td); 698 break; 699 } 700 701 case NGM_KSOCKET_ACCEPT: 702 { 703 /* Sanity check */ 704 if (msg->header.arglen != 0) 705 ERROUT(EINVAL); 706 if (so == NULL) 707 ERROUT(ENXIO); 708 709 /* Make sure the socket is capable of accepting */ 710 if (!(so->so_options & SO_ACCEPTCONN)) 711 ERROUT(EINVAL); 712 if (priv->flags & KSF_ACCEPTING) 713 ERROUT(EALREADY); 714 715 error = ng_ksocket_check_accept(priv); 716 if (error != 0 && error != EWOULDBLOCK) 717 ERROUT(error); 718 719 /* 720 * If a connection is already complete, take it. 721 * Otherwise let the upcall function deal with 722 * the connection when it comes in. 723 */ 724 priv->response_token = msg->header.token; 725 priv->response_addr = NGI_RETADDR(item); 726 if (error == 0) { 727 ng_ksocket_finish_accept(priv); 728 } else 729 priv->flags |= KSF_ACCEPTING; 730 break; 731 } 732 733 case NGM_KSOCKET_CONNECT: 734 { 735 struct sockaddr *const sa 736 = (struct sockaddr *)msg->data; 737 738 /* Sanity check */ 739 if (msg->header.arglen < SADATA_OFFSET 740 || msg->header.arglen < sa->sa_len) 741 ERROUT(EINVAL); 742 if (so == NULL) 743 ERROUT(ENXIO); 744 745 /* Do connect */ 746 if ((so->so_state & SS_ISCONNECTING) != 0) 747 ERROUT(EALREADY); 748 if ((error = soconnect(so, sa, td, TRUE)) != 0) { 749 soclrstate(so, SS_ISCONNECTING); 750 ERROUT(error); 751 } 752 if ((so->so_state & SS_ISCONNECTING) != 0) { 753 /* We will notify the sender when we connect */ 754 priv->response_token = msg->header.token; 755 priv->response_addr = NGI_RETADDR(item); 756 priv->flags |= KSF_CONNECTING; 757 ERROUT(EINPROGRESS); 758 } 759 break; 760 } 761 762 case NGM_KSOCKET_GETNAME: 763 case NGM_KSOCKET_GETPEERNAME: 764 { 765 struct sockaddr *sa = NULL; 766 int len; 767 768 /* Sanity check */ 769 if (msg->header.arglen != 0) 770 ERROUT(EINVAL); 771 if (so == NULL) 772 ERROUT(ENXIO); 773 774 /* Get function */ 775 if (msg->header.cmd == NGM_KSOCKET_GETPEERNAME) { 776 if ((so->so_state 777 & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) 778 ERROUT(ENOTCONN); 779 error = so_pru_peeraddr(so, &sa); 780 } else { 781 error = so_pru_sockaddr(so, &sa); 782 } 783 784 /* Get local or peer address */ 785 if (error != 0) 786 goto bail; 787 len = (sa == NULL) ? 0 : sa->sa_len; 788 789 /* Send it back in a response */ 790 NG_MKRESPONSE(resp, msg, len, M_WAITOK | M_NULLOK); 791 if (resp == NULL) { 792 error = ENOMEM; 793 goto bail; 794 } 795 bcopy(sa, resp->data, len); 796 797 bail: 798 /* Cleanup */ 799 if (sa != NULL) 800 kfree(sa, M_SONAME); 801 break; 802 } 803 804 case NGM_KSOCKET_GETOPT: 805 { 806 struct ng_ksocket_sockopt *ksopt = 807 (struct ng_ksocket_sockopt *)msg->data; 808 struct sockopt sopt; 809 810 /* Sanity check */ 811 if (msg->header.arglen != sizeof(*ksopt)) 812 ERROUT(EINVAL); 813 if (so == NULL) 814 ERROUT(ENXIO); 815 816 /* Get response with room for option value */ 817 NG_MKRESPONSE(resp, msg, sizeof(*ksopt) 818 + NG_KSOCKET_MAX_OPTLEN, M_WAITOK | M_NULLOK); 819 if (resp == NULL) 820 ERROUT(ENOMEM); 821 822 /* Get socket option, and put value in the response */ 823 sopt.sopt_dir = SOPT_GET; 824 sopt.sopt_level = ksopt->level; 825 sopt.sopt_name = ksopt->name; 826 sopt.sopt_td = NULL; 827 sopt.sopt_valsize = NG_KSOCKET_MAX_OPTLEN; 828 ksopt = (struct ng_ksocket_sockopt *)resp->data; 829 sopt.sopt_val = ksopt->value; 830 if ((error = sogetopt(so, &sopt)) != 0) { 831 NG_FREE_MSG(resp); 832 break; 833 } 834 835 /* Set actual value length */ 836 resp->header.arglen = sizeof(*ksopt) 837 + sopt.sopt_valsize; 838 break; 839 } 840 841 case NGM_KSOCKET_SETOPT: 842 { 843 struct ng_ksocket_sockopt *const ksopt = 844 (struct ng_ksocket_sockopt *)msg->data; 845 const int valsize = msg->header.arglen - sizeof(*ksopt); 846 struct sockopt sopt; 847 848 /* Sanity check */ 849 if (valsize < 0) 850 ERROUT(EINVAL); 851 if (so == NULL) 852 ERROUT(ENXIO); 853 854 /* Set socket option */ 855 sopt.sopt_dir = SOPT_SET; 856 sopt.sopt_level = ksopt->level; 857 sopt.sopt_name = ksopt->name; 858 sopt.sopt_val = ksopt->value; 859 sopt.sopt_valsize = valsize; 860 sopt.sopt_td = NULL; 861 error = sosetopt(so, &sopt); 862 break; 863 } 864 865 default: 866 error = EINVAL; 867 break; 868 } 869 break; 870 default: 871 error = EINVAL; 872 break; 873 } 874 done: 875 NG_RESPOND_MSG(error, node, item, resp); 876 NG_FREE_MSG(msg); 877 return (error); 878 } 879 880 /* 881 * Receive incoming data on our hook. Send it out the socket. 882 */ 883 static int 884 ng_ksocket_rcvdata(hook_p hook, item_p item) 885 { 886 struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ 887 const node_p node = NG_HOOK_NODE(hook); 888 const priv_p priv = NG_NODE_PRIVATE(node); 889 struct socket *const so = priv->so; 890 struct sockaddr *sa = NULL; 891 int error; 892 struct mbuf *m; 893 struct sa_tag *stag; 894 895 /* Extract data */ 896 NGI_GET_M(item, m); 897 NG_FREE_ITEM(item); 898 899 /* 900 * Look if socket address is stored in packet tags. 901 * If sockaddr is ours, or provided by a third party (zero id), 902 * then we accept it. 903 */ 904 if (((stag = (struct sa_tag *)m_tag_locate(m, NGM_KSOCKET_COOKIE, 905 NG_KSOCKET_TAG_SOCKADDR, NULL)) != NULL) && 906 (stag->id == NG_NODE_ID(node) || stag->id == 0)) 907 sa = &stag->sa; 908 909 /* Reset specific mbuf flags to prevent addressing problems. */ 910 m->m_flags &= ~(M_BCAST|M_MCAST); 911 912 /* Send packet */ 913 error = sosend(so, sa, 0, m, 0, 0, td); 914 915 return (error); 916 } 917 918 /* 919 * Destroy node 920 */ 921 static int 922 ng_ksocket_shutdown(node_p node) 923 { 924 const priv_p priv = NG_NODE_PRIVATE(node); 925 priv_p embryo; 926 927 /* Close our socket (if any) */ 928 if (priv->so != NULL) { 929 atomic_clear_int(&priv->so->so_rcv.ssb_flags, SSB_UPCALL); 930 atomic_clear_int(&priv->so->so_snd.ssb_flags, SSB_UPCALL); 931 priv->so->so_upcall = NULL; 932 soclose(priv->so, FNONBLOCK); 933 priv->so = NULL; 934 } 935 936 /* If we are an embryo, take ourselves out of the parent's list */ 937 if (priv->flags & KSF_EMBRYONIC) { 938 LIST_REMOVE(priv, siblings); 939 priv->flags &= ~KSF_EMBRYONIC; 940 } 941 942 /* Remove any embryonic children we have */ 943 while (!LIST_EMPTY(&priv->embryos)) { 944 embryo = LIST_FIRST(&priv->embryos); 945 ng_rmnode_self(embryo->node); 946 } 947 948 /* Take down netgraph node */ 949 bzero(priv, sizeof(*priv)); 950 kfree(priv, M_NETGRAPH); 951 NG_NODE_SET_PRIVATE(node, NULL); 952 NG_NODE_UNREF(node); /* let the node escape */ 953 return (0); 954 } 955 956 /* 957 * Hook disconnection 958 */ 959 static int 960 ng_ksocket_disconnect(hook_p hook) 961 { 962 KASSERT(NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0, 963 ("%s: numhooks=%d?", __func__, 964 NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)))); 965 if (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) 966 ng_rmnode_self(NG_HOOK_NODE(hook)); 967 return (0); 968 } 969 970 /************************************************************************ 971 HELPER STUFF 972 ************************************************************************/ 973 /* 974 * You should not "just call" a netgraph node function from an external 975 * asynchronous event. This is because in doing so you are ignoring the 976 * locking on the netgraph nodes. Instead call your function via ng_send_fn(). 977 * This will call the function you chose, but will first do all the 978 * locking rigmarole. Your function MAY only be called at some distant future 979 * time (several millisecs away) so don't give it any arguments 980 * that may be revoked soon (e.g. on your stack). 981 * 982 * To decouple stack, we use queue version of ng_send_fn(). 983 */ 984 985 static void 986 ng_ksocket_incoming(struct socket *so, void *arg, int waitflag) 987 { 988 const node_p node = arg; 989 const priv_p priv = NG_NODE_PRIVATE(node); 990 int wait = ((waitflag & M_WAITOK) ? NG_WAITOK : 0) | NG_QUEUE; 991 992 /* 993 * Even if node is not locked, as soon as we are called, we assume 994 * it exist and it's private area is valid. With some care we can 995 * access it. Mark node that incoming event for it was sent to 996 * avoid unneded queue trashing. 997 */ 998 if (atomic_cmpset_int(&priv->fn_sent, 0, 1) && 999 ng_send_fn1(node, NULL, &ng_ksocket_incoming2, so, 0, wait)) { 1000 atomic_store_rel_int(&priv->fn_sent, 0); 1001 } 1002 } 1003 1004 1005 /* 1006 * When incoming data is appended to the socket, we get notified here. 1007 * This is also called whenever a significant event occurs for the socket. 1008 * Our original caller may have queued this even some time ago and 1009 * we cannot trust that he even still exists. The node however is being 1010 * held with a reference by the queueing code and guarantied to be valid. 1011 */ 1012 static void 1013 ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int arg2) 1014 { 1015 struct socket *so = arg1; 1016 const priv_p priv = NG_NODE_PRIVATE(node); 1017 struct ng_mesg *response; 1018 int flags, error; 1019 1020 crit_enter(); 1021 1022 /* so = priv->so; *//* XXX could have derived this like so */ 1023 KASSERT(so == priv->so, ("%s: wrong socket", __func__)); 1024 1025 /* Allow next incoming event to be queued. */ 1026 atomic_store_rel_int(&priv->fn_sent, 0); 1027 1028 /* Check whether a pending connect operation has completed */ 1029 if (priv->flags & KSF_CONNECTING) { 1030 if ((error = so->so_error) != 0) { 1031 so->so_error = 0; 1032 soclrstate(so, SS_ISCONNECTING); 1033 } 1034 if (!(so->so_state & SS_ISCONNECTING)) { 1035 NG_MKMESSAGE(response, NGM_KSOCKET_COOKIE, 1036 NGM_KSOCKET_CONNECT, sizeof(int32_t), M_WAITOK | M_NULLOK); 1037 if (response != NULL) { 1038 response->header.flags |= NGF_RESP; 1039 response->header.token = priv->response_token; 1040 *(int32_t *)response->data = error; 1041 /* 1042 * send an async "response" message 1043 * to the node that set us up 1044 * (if it still exists) 1045 */ 1046 NG_SEND_MSG_ID(error, node, 1047 response, priv->response_addr, 0); 1048 } 1049 priv->flags &= ~KSF_CONNECTING; 1050 } 1051 } 1052 1053 /* Check whether a pending accept operation has completed */ 1054 if (priv->flags & KSF_ACCEPTING) { 1055 error = ng_ksocket_check_accept(priv); 1056 if (error != EWOULDBLOCK) 1057 priv->flags &= ~KSF_ACCEPTING; 1058 if (error == 0) 1059 ng_ksocket_finish_accept(priv); 1060 } 1061 1062 /* 1063 * If we don't have a hook, we must handle data events later. When 1064 * the hook gets created and is connected, this upcall function 1065 * will be called again. 1066 */ 1067 if (priv->hook == NULL) { 1068 crit_exit(); 1069 return; 1070 } 1071 1072 /* Read and forward available mbuf's */ 1073 while (1) { 1074 struct sockaddr *sa = NULL; 1075 struct sockbuf sio; 1076 struct mbuf *n; 1077 1078 sbinit(&sio, 1000000000); 1079 flags = MSG_DONTWAIT; 1080 1081 /* Try to get next packet from socket */ 1082 error = soreceive(so, 1083 ((so->so_state & SS_ISCONNECTED) ? NULL : &sa), 1084 NULL, &sio, NULL, &flags); 1085 if (error) 1086 break; 1087 1088 /* See if we got anything */ 1089 if (sio.sb_mb == NULL) { 1090 if (sa != NULL) 1091 kfree(sa, M_SONAME); 1092 break; 1093 } 1094 1095 /* 1096 * Don't trust the various socket layers to get the 1097 * packet header and length correct (e.g. kern/15175). 1098 * 1099 * Also, do not trust that soreceive() will clear m_nextpkt 1100 * for us (e.g. kern/84952, kern/82413). 1101 */ 1102 sio.sb_mb->m_pkthdr.csum_flags = 0; 1103 sio.sb_mb->m_pkthdr.len = 0; 1104 for (n = sio.sb_mb; n != NULL; n = n->m_next) { 1105 sio.sb_mb->m_pkthdr.len += n->m_len; 1106 n->m_nextpkt = NULL; 1107 } 1108 1109 /* Put peer's socket address (if any) into a tag */ 1110 if (sa != NULL) { 1111 struct sa_tag *stag; 1112 1113 stag = (struct sa_tag *)m_tag_alloc(NGM_KSOCKET_COOKIE, 1114 NG_KSOCKET_TAG_SOCKADDR, sizeof(ng_ID_t) + 1115 sa->sa_len, M_NOWAIT); 1116 if (stag == NULL) { 1117 kfree(sa, M_SONAME); 1118 goto sendit; 1119 } 1120 bcopy(sa, &stag->sa, sa->sa_len); 1121 kfree(sa, M_SONAME); 1122 stag->id = NG_NODE_ID(node); 1123 m_tag_prepend(sio.sb_mb, &stag->tag); 1124 } 1125 1126 sendit: /* Forward data with optional peer sockaddr as packet tag */ 1127 NG_SEND_DATA_ONLY(error, priv->hook, sio.sb_mb); 1128 } 1129 1130 /* 1131 * If the peer has closed the connection, forward a 0-length mbuf 1132 * to indicate end-of-file. 1133 */ 1134 if (so->so_state & SS_CANTRCVMORE && !(priv->flags & KSF_EOFSEEN)) { 1135 struct mbuf *m; 1136 1137 MGETHDR(m, M_NOWAIT, MT_DATA); 1138 if (m != NULL) { 1139 m->m_len = m->m_pkthdr.len = 0; 1140 NG_SEND_DATA_ONLY(error, priv->hook, m); 1141 } 1142 priv->flags |= KSF_EOFSEEN; 1143 } 1144 crit_exit(); 1145 } 1146 1147 /* 1148 * Check for a completed incoming connection and return 0 if one is found. 1149 * Otherwise return the appropriate error code. 1150 */ 1151 static int 1152 ng_ksocket_check_accept(priv_p priv) 1153 { 1154 struct socket *const head = priv->so; 1155 int error; 1156 1157 if ((error = head->so_error) != 0) { 1158 head->so_error = 0; 1159 return error; 1160 } 1161 /* Unlocked read. */ 1162 if (TAILQ_EMPTY(&head->so_comp)) { 1163 if (head->so_state & SS_CANTRCVMORE) 1164 return ECONNABORTED; 1165 return EWOULDBLOCK; 1166 } 1167 return 0; 1168 } 1169 1170 /* 1171 * Handle the first completed incoming connection, assumed to be already 1172 * on the socket's so_comp queue. 1173 */ 1174 static void 1175 ng_ksocket_finish_accept(priv_p priv) 1176 { 1177 struct socket *const head = priv->so; 1178 struct socket *so; 1179 struct sockaddr *sa = NULL; 1180 struct ng_mesg *resp; 1181 struct ng_ksocket_accept *resp_data; 1182 node_p node; 1183 priv_p priv2; 1184 int len; 1185 int error; 1186 1187 lwkt_getpooltoken(head); 1188 so = TAILQ_FIRST(&head->so_comp); 1189 if (so == NULL) { /* Should never happen */ 1190 lwkt_relpooltoken(head); 1191 return; 1192 } 1193 TAILQ_REMOVE(&head->so_comp, so, so_list); 1194 head->so_qlen--; 1195 soclrstate(so, SS_COMP); 1196 so->so_head = NULL; 1197 soreference(so); 1198 lwkt_relpooltoken(head); 1199 1200 /* XXX KNOTE(&head->so_rcv.ssb_sel.si_note, 0); */ 1201 1202 soaccept(so, &sa); 1203 1204 len = OFFSETOF(struct ng_ksocket_accept, addr); 1205 if (sa != NULL) 1206 len += sa->sa_len; 1207 1208 NG_MKMESSAGE(resp, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, len, 1209 M_WAITOK | M_NULLOK); 1210 if (resp == NULL) { 1211 soclose(so, FNONBLOCK); 1212 goto out; 1213 } 1214 resp->header.flags |= NGF_RESP; 1215 resp->header.token = priv->response_token; 1216 1217 /* Clone a ksocket node to wrap the new socket */ 1218 error = ng_make_node_common(&ng_ksocket_typestruct, &node); 1219 if (error) { 1220 kfree(resp, M_NETGRAPH); 1221 soclose(so, FNONBLOCK); 1222 goto out; 1223 } 1224 1225 if (ng_ksocket_constructor(node) != 0) { 1226 NG_NODE_UNREF(node); 1227 kfree(resp, M_NETGRAPH); 1228 soclose(so, FNONBLOCK); 1229 goto out; 1230 } 1231 1232 priv2 = NG_NODE_PRIVATE(node); 1233 priv2->so = so; 1234 priv2->flags |= KSF_CLONED | KSF_EMBRYONIC; 1235 1236 /* 1237 * Insert the cloned node into a list of embryonic children 1238 * on the parent node. When a hook is created on the cloned 1239 * node it will be removed from this list. When the parent 1240 * is destroyed it will destroy any embryonic children it has. 1241 */ 1242 LIST_INSERT_HEAD(&priv->embryos, priv2, siblings); 1243 1244 so->so_upcallarg = (caddr_t)node; 1245 so->so_upcall = ng_ksocket_incoming; 1246 atomic_set_int(&priv->so->so_rcv.ssb_flags, SSB_UPCALL); 1247 atomic_set_int(&priv->so->so_snd.ssb_flags, SSB_UPCALL); 1248 1249 /* Fill in the response data and send it or return it to the caller */ 1250 resp_data = (struct ng_ksocket_accept *)resp->data; 1251 resp_data->nodeid = NG_NODE_ID(node); 1252 if (sa != NULL) 1253 bcopy(sa, &resp_data->addr, sa->sa_len); 1254 NG_SEND_MSG_ID(error, node, resp, priv->response_addr, 0); 1255 1256 out: 1257 if (sa != NULL) 1258 kfree(sa, M_SONAME); 1259 } 1260 1261 /* 1262 * Parse out either an integer value or an alias. 1263 */ 1264 static int 1265 ng_ksocket_parse(const struct ng_ksocket_alias *aliases, 1266 const char *s, int family) 1267 { 1268 int k, val; 1269 char *eptr; 1270 1271 /* Try aliases */ 1272 for (k = 0; aliases[k].name != NULL; k++) { 1273 if (strcmp(s, aliases[k].name) == 0 1274 && aliases[k].family == family) 1275 return aliases[k].value; 1276 } 1277 1278 /* Try parsing as a number */ 1279 val = (int)strtoul(s, &eptr, 10); 1280 if (val < 0 || *eptr != '\0') 1281 return (-1); 1282 return (val); 1283 } 1284 1285