INTERPOSE (connect, int, int sockfd, const struct sockaddr * addr, socklen_t addrlen) { v4v_addr_t peer, me; char *val, *end; int addend, ret; CHECK_INTERPOSE (connect); if (!is_our_fd (sockfd)) return orig_connect (sockfd, addr, addrlen); if (v4v_map_sa_to_v4va (&peer, addr, addrlen)) return -EINVAL; /* Bind the socket to a specific port if requested */ val = getenv ("V4V_CLIENT_PORT_ADDEND"); if (val != NULL) { addend = strtol(val, &end, 10); /* Sanitize the addend */ if (end == NULL || *end != '\0' || addend < 0) return -EINVAL; me.domain = V4V_DOMID_ANY; me.port = peer.port + addend; DEBUG_PRINTF ("BINDING CLIENT TO port %d\n", (int) me.port); DEBUG_PRINTF (" AND SET %d AS THE PARTNER\n", (int) peer.domain); ret = v4v_bind(sockfd, &me, peer.domain); if (ret) return ret; } DEBUG_PRINTF ("CONNECTING TO %d:%d\n", (int) peer.domain, (int) peer.port); return v4v_connect (sockfd, &peer); }
INTERPOSE (sendto, ssize_t, int sockfd, const void *buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen) { v4v_addr_t peer; CHECK_INTERPOSE (sendto); if (!is_our_fd (sockfd)) return orig_sendto (sockfd, buf, len, flags, dest_addr, addrlen); if (dest_addr && v4v_map_sa_to_v4va (&peer, dest_addr, addrlen)) return -EINVAL; return v4v_sendto (sockfd, buf, len, flags, dest_addr ? &peer : NULL); }
INTERPOSE (connect, int, int sockfd, const struct sockaddr * addr, socklen_t addrlen) { v4v_addr_t peer; CHECK_INTERPOSE (connect); if (!is_our_fd (sockfd)) return orig_connect (sockfd, addr, addrlen); if (v4v_map_sa_to_v4va (&peer, addr, addrlen)) return -EINVAL; DEBUG_PRINTF ("CONNECTING TO %d:%d\n", (int) peer.domain, (int) peer.port); return v4v_connect (sockfd, &peer); }
INTERPOSE (bind, int, int sockfd, const struct sockaddr * addr, socklen_t addrlen) { v4v_addr_t v4va; CHECK_INTERPOSE (bind); if (!is_our_fd (sockfd)) return orig_bind (sockfd, addr, addrlen); if (addr->sa_family == AF_XENV4V) register_af (sockfd); else unregister_af (sockfd); if (v4v_map_sa_to_v4va (&v4va, addr, addrlen)) return -EINVAL; return v4v_bind (sockfd, &v4va, getenv ("V4V_ACCEPT_DOM0_ONLY") ? 0 : V4V_DOMID_NONE); }
INTERPOSE (sendmsg, ssize_t, int sockfd, const struct msghdr * msg, int flags) { struct msghdr v4vmsg; v4v_addr_t v4va; CHECK_INTERPOSE (sendmsg); if (!is_our_fd (sockfd)) return orig_sendmsg (sockfd, msg, flags); if (!msg) return -EINVAL; v4vmsg = *msg; if (v4vmsg.msg_name) { if (v4v_map_sa_to_v4va(&v4va, v4vmsg.msg_name, v4vmsg.msg_namelen)) return -EINVAL; v4vmsg.msg_name = &v4va; v4vmsg.msg_namelen = sizeof(v4va); } return v4v_sendmsg (sockfd, &v4vmsg, flags); }