function channel_create_stdapi_net_udp_client($req, &$pkt) { my_print("creating udp client"); $peer_host_tlv = packet_get_tlv($req, TLV_TYPE_PEER_HOST); $peer_port_tlv = packet_get_tlv($req, TLV_TYPE_PEER_PORT); # We can't actually do anything with local_host and local_port because PHP # doesn't let us specify these values in any of the exposed socket API # functions. #$local_host_tlv = packet_get_tlv($req, TLV_TYPE_LOCAL_HOST); #$local_port_tlv = packet_get_tlv($req, TLV_TYPE_LOCAL_PORT); $sock = connect($peer_host_tlv['value'], $peer_port_tlv['value'], 'udp'); my_print("UDP channel on {$sock}"); if (!$sock) { return ERROR_CONNECTION_ERROR; } # # If we got here, the connection worked, respond with the new channel ID # $id = register_channel($sock); packet_add_tlv($pkt, create_tlv(TLV_TYPE_CHANNEL_ID, $id)); add_reader($sock); return ERROR_SUCCESS; }
function core_channel_interact($req, &$pkt) { global $readers; my_print("doing channel interact"); $chan_tlv = packet_get_tlv($req, TLV_TYPE_CHANNEL_ID); $id = $chan_tlv['value']; # True means start interacting, False means stop $toggle_tlv = packet_get_tlv($req, TLV_TYPE_BOOL); $c = get_channel_by_id($id); if ($c) { if ($toggle_tlv['value']) { # Start interacting. If we're already interacting with this # channel, it's an error and we should return failure. if (!in_array($c[1], $readers)) { # stdout add_reader($c[1]); # Make sure we don't add the same resource twice in the case # that stdin == stderr if (array_key_exists(2, $c) && $c[1] != $c[2]) { # stderr add_reader($c[2]); } $ret = ERROR_SUCCESS; } else { # Already interacting $ret = ERROR_FAILURE; } } else { # Stop interacting. If we're not interacting yet with this # channel, it's an error and we should return failure. if (in_array($c[1], $readers)) { remove_reader($c[1]); # stdout remove_reader($c[2]); # stderr $ret = ERROR_SUCCESS; } else { # Not interacting. This is technically failure, but it seems # the client sends us two of these requests in quick succession # causing the second one to always return failure. When that # happens we fail to clean up properly, so always return # success here. $ret = ERROR_SUCCESS; } } } else { # Not a valid channel my_print("Trying to interact with an invalid channel"); $ret = ERROR_FAILURE; } return $ret; }
function core_channel_interact($req, &$pkt) { global $readers; my_print("doing channel interact"); $chan_tlv = packet_get_tlv($req, TLV_TYPE_CHANNEL_ID); $id = $chan_tlv['value']; # True means start interacting, False means stop $toggle_tlv = packet_get_tlv($req, TLV_TYPE_BOOL); $c = get_channel_by_id($id); if ($c) { if ($toggle_tlv['value']) { # Start interacting. If we're already interacting with this # channel, it's an error and we should return failure. if (!in_array($c[1], $readers)) { # stdout add_reader($c[1]); # stderr, don't care if it fails if (array_key_exists(2, $c) && $c[1] != $c[2]) { add_reader($c[2]); } $ret = ERROR_SUCCESS; } else { # Already interacting $ret = ERROR_FAILURE; } } else { # Stop interacting. If we're not interacting yet with this # channel, it's an error and we should return failure. if (in_array($c[1], $readers)) { remove_reader($c[1]); # stdout remove_reader($c[2]); # stderr $ret = ERROR_SUCCESS; } else { # Not interacting $ret = ERROR_FAILURE; } } } else { # Not a valid channel $ret = ERROR_FAILURE; } return $ret; }