| 599 | } |
| 600 | |
| 601 | static int |
| 602 | ng_ksocket_connect(hook_p hook) |
| 603 | { |
| 604 | node_p node = NG_HOOK_NODE(hook); |
| 605 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 606 | struct socket *const so = priv->so; |
| 607 | |
| 608 | /* Add our hook for incoming data and other events */ |
| 609 | SOCKBUF_LOCK(&priv->so->so_rcv); |
| 610 | soupcall_set(priv->so, SO_RCV, ng_ksocket_incoming, node); |
| 611 | SOCKBUF_UNLOCK(&priv->so->so_rcv); |
| 612 | SOCKBUF_LOCK(&priv->so->so_snd); |
| 613 | soupcall_set(priv->so, SO_SND, ng_ksocket_incoming, node); |
| 614 | SOCKBUF_UNLOCK(&priv->so->so_snd); |
| 615 | SOCK_LOCK(priv->so); |
| 616 | priv->so->so_state |= SS_NBIO; |
| 617 | SOCK_UNLOCK(priv->so); |
| 618 | /* |
| 619 | * --Original comment-- |
| 620 | * On a cloned socket we may have already received one or more |
| 621 | * upcalls which we couldn't handle without a hook. Handle |
| 622 | * those now. |
| 623 | * We cannot call the upcall function directly |
| 624 | * from here, because until this function has returned our |
| 625 | * hook isn't connected. |
| 626 | * |
| 627 | * ---meta comment for -current --- |
| 628 | * XXX This is dubius. |
| 629 | * Upcalls between the time that the hook was |
| 630 | * first created and now (on another processesor) will |
| 631 | * be earlier on the queue than the request to finalise the hook. |
| 632 | * By the time the hook is finalised, |
| 633 | * The queued upcalls will have happened and the code |
| 634 | * will have discarded them because of a lack of a hook. |
| 635 | * (socket not open). |
| 636 | * |
| 637 | * This is a bad byproduct of the complicated way in which hooks |
| 638 | * are now created (3 daisy chained async events). |
| 639 | * |
| 640 | * Since we are a netgraph operation |
| 641 | * We know that we hold a lock on this node. This forces the |
| 642 | * request we make below to be queued rather than implemented |
| 643 | * immediately which will cause the upcall function to be called a bit |
| 644 | * later. |
| 645 | * However, as we will run any waiting queued operations immediately |
| 646 | * after doing this one, if we have not finalised the other end |
| 647 | * of the hook, those queued operations will fail. |
| 648 | */ |
| 649 | if (priv->flags & KSF_CLONED) { |
| 650 | ng_send_fn(node, NULL, &ng_ksocket_incoming2, so, M_NOWAIT); |
| 651 | } |
| 652 | |
| 653 | return (0); |
| 654 | } |
| 655 | |
| 656 | /* |
| 657 | * Receive a control message |
nothing calls this directly
no test coverage detected