* Connect the data socket to a named control socket node. */
| 690 | * Connect the data socket to a named control socket node. |
| 691 | */ |
| 692 | static int |
| 693 | ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp) |
| 694 | { |
| 695 | struct sockaddr_ng *sap; |
| 696 | node_p farnode; |
| 697 | struct ngsock *priv; |
| 698 | int error; |
| 699 | item_p item; |
| 700 | |
| 701 | /* If we are already connected, don't do it again. */ |
| 702 | if (pcbp->sockdata != NULL) |
| 703 | return (EISCONN); |
| 704 | |
| 705 | /* |
| 706 | * Find the target (victim) and check it doesn't already have |
| 707 | * a data socket. Also check it is a 'socket' type node. |
| 708 | * Use ng_package_data() and ng_address_path() to do this. |
| 709 | */ |
| 710 | |
| 711 | sap = (struct sockaddr_ng *) nam; |
| 712 | /* The item will hold the node reference. */ |
| 713 | item = ng_package_data(NULL, NG_WAITOK); |
| 714 | |
| 715 | if ((error = ng_address_path(NULL, item, sap->sg_data, 0))) |
| 716 | return (error); /* item is freed on failure */ |
| 717 | |
| 718 | /* |
| 719 | * Extract node from item and free item. Remember we now have |
| 720 | * a reference on the node. The item holds it for us. |
| 721 | * when we free the item we release the reference. |
| 722 | */ |
| 723 | farnode = item->el_dest; /* shortcut */ |
| 724 | if (strcmp(farnode->nd_type->name, NG_SOCKET_NODE_TYPE) != 0) { |
| 725 | NG_FREE_ITEM(item); /* drop the reference to the node */ |
| 726 | return (EINVAL); |
| 727 | } |
| 728 | priv = NG_NODE_PRIVATE(farnode); |
| 729 | if (priv->datasock != NULL) { |
| 730 | NG_FREE_ITEM(item); /* drop the reference to the node */ |
| 731 | return (EADDRINUSE); |
| 732 | } |
| 733 | |
| 734 | /* |
| 735 | * Link the PCB and the private data struct. and note the extra |
| 736 | * reference. Drop the extra reference on the node. |
| 737 | */ |
| 738 | mtx_lock(&priv->mtx); |
| 739 | priv->datasock = pcbp; |
| 740 | pcbp->sockdata = priv; |
| 741 | pcbp->node_id = priv->node->nd_ID; /* hint for netstat(1) */ |
| 742 | priv->refs++; |
| 743 | mtx_unlock(&priv->mtx); |
| 744 | NG_FREE_ITEM(item); /* drop the reference to the node */ |
| 745 | return (0); |
| 746 | } |
| 747 | |
| 748 | /* |
| 749 | * Binding a socket means giving the corresponding node a name |
no test coverage detected