static void port_server_cmd_create(char * token, Channel * c) { int err = 0; PortAttribute * attrs = NULL; PortServer * server; Channel * port_channel; json_read_struct(&c->inp, read_port_server_property, &attrs); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); /* In case the current channel is a proxy (value-add), use the * target channel. Otherwise, use the provided channel. */ port_channel = proxy_get_target_channel(c); if (port_channel == NULL) port_channel = c; server = create_port_server(c, attrs, NULL, NULL, NULL, NULL); if (server == NULL) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err) write_stringz(&c->out, "null"); else { write_port_server_info(&c->out, server); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
/* void remove_port_redirection(PortServer * redir) { port_server_shutdown(redir->server); } */ PortServer * create_port_redirection(PortRedirectionInfo * port) { PortServer * server; assert (port != NULL); assert (port->c != NULL); if (port == NULL || port->c == NULL) { free_port_redirection_info(port); errno = EINVAL; return NULL; } ini_portforwarding(); /* We do not accept specifying a target_port (legacy) and port attributes */ if (port->target_port != 0 && port->attrs != NULL) { free_port_redirection_info(port); errno = EINVAL; return NULL; } if (port->target_port != 0) { char port_str[16]; PortAttribute * attr = (PortAttribute *)loc_alloc_zero(sizeof(PortAttribute)); snprintf(port_str, 16, "%d", port->target_port); attr->name = loc_strdup("Port"); attr->value = loc_strdup(port_str); attr->next = port->attrs; port->attrs = attr; } server = create_port_server(port->c, port); if (server == NULL) { free_port_redirection_info(port); loc_free(server); return NULL; } else { server->redir_info = port; port->local_port = server->local_port; server->auto_connect = port->auto_connect; server->auto_connect_period = port->auto_connect_period == 0 ? 3 : port->auto_connect_period; server->connect_callback = port->connect_callback; server->disconnect_callback = port->disconnect_callback; server->recv_callback = port->recv_callback; server->callback_data = port->callback_data; if (server->auto_connect) { /* If auto connect mode is set, immediately try to connect to the * port. */ port_connection_open(server, server->is_udp ? server->sock : -1); } return server; } }