diff --git a/src/core/hub.c b/src/core/hub.c index 9a618b2..8d91fa9 100644 --- a/src/core/hub.c +++ b/src/core/hub.c @@ -841,6 +841,15 @@ struct hub_info* hub_start_service(struct hub_config* config) // Start the hub command sub-system hub->commands = command_initialize(hub); + +#ifdef LINK_SUPPORT + if (*config->hub_link_connect) + { + link_connect_uri(hub, config->hub_link_connect); + } +#endif + + return hub; } diff --git a/src/core/link.c b/src/core/link.c index e90f0e9..144ca14 100644 --- a/src/core/link.c +++ b/src/core/link.c @@ -20,6 +20,7 @@ #include "uhub.h" #ifdef LINK_SUPPORT +static int link_send_support(struct hub_link* link); static void link_net_event(struct net_connection* con, int event, void *arg) { @@ -56,7 +57,8 @@ static void link_net_event(struct net_connection* con, int event, void *arg) void link_disconnect(struct hub_link* link) { - net_con_close(link->connection); + if (link->connection) + net_con_close(link->connection); link->connection = NULL; ioq_send_destroy(link->send_queue); @@ -96,22 +98,92 @@ struct hub_link* link_create(struct hub_info* hub, struct net_connection* con, s return link; } -struct hub_link* link_connect(struct hub_info* hub, const char* address) +static void link_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con, void* ptr) { - struct hub_link* link = link_create_internal(hub); + struct hub_link* link = (struct hub_link*) ptr; + link->connect_job = NULL; - // FIXME - no IPv6 support, no DNS resolution, no failover addresses etc. - int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sd == -1) + LOG_DEBUG("link_connect_callback()"); + + switch (status) { - hub_free(link); + case net_connect_status_ok: + link->connection = con; + net_con_reinitialize(link->connection, link_net_event, link, NET_EVENT_READ); + // FIXME: send handshake here + link_send_support(link); + break; + + case net_connect_status_host_not_found: + case net_connect_status_no_address: + case net_connect_status_dns_error: + case net_connect_status_refused: + case net_connect_status_unreachable: + case net_connect_status_timeout: + case net_connect_status_socket_error: + // FIXME: Unable to connect - start timer and re-try connection establishment! + break; + } +} + +struct link_address +{ + char host[256]; + uint16_t port; +}; + +static int link_parse_address(const char* arg, struct link_address* addr) +{ + int port; + char* split; + + memset(addr, 0, sizeof(struct link_address)); + + /* Split hostname and port (if possible) */ + split = strrchr(arg, ':'); + if (split == 0 || strlen(split) < 2 || strlen(split) > 6) + return 0; + + /* Ensure port number is valid */ + port = strtol(split+1, NULL, 10); + if (port <= 0 || port > 65535) + return 0; + + memcpy(addr->host, arg, &split[0] - &arg[0]); + addr->port = port; + return 1; +} + + +struct hub_link* link_connect_uri(struct hub_info* hub, const char* address) +{ + struct link_address link_address; + if (!link_parse_address(address, &link_address)) + { + LOG_INFO("Invalid master hub link address"); return NULL; } - link->connection = net_con_create(); - net_con_initialize(link->connection, sd, link_net_event, link, 0); + return link_connect(hub, link_address.host, link_address.port); +} + + +struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port) +{ + struct hub_link* link = link_create_internal(hub); + + LOG_DEBUG("Connecting to master link at %s:%d...", address, port); link->mode = link_mode_client; + link->connect_job = net_con_connect(address, port, link_connect_callback, link); + if (!link->connect_job) + { + // FIXME: Immediate failure! + LOG_DEBUG("Error connecting to master hub link."); + link_disconnect(link); + return NULL; + } + return link; } @@ -433,4 +505,4 @@ int link_handle_read(struct hub_link* link) } -#endif /* LINK_SUPPORT */ \ No newline at end of file +#endif /* LINK_SUPPORT */ diff --git a/src/core/link.h b/src/core/link.h index c1c81b2..deaf6a8 100644 --- a/src/core/link.h +++ b/src/core/link.h @@ -32,6 +32,7 @@ struct hub_link struct ioq_send* send_queue; struct ioq_recv* recv_queue; struct net_connection* connection; /** Connection data */ + struct net_connect_handle* connect_job; /** Only used when establishing a connection in client mode */ struct hub_info* hub; int flags; }; @@ -44,7 +45,8 @@ extern struct hub_link* link_create(struct hub_info* hub, struct net_connection* /** * Connect this hub to an upstream server (act as a link client). */ -extern struct hub_link* link_connect(struct hub_info* hub, const char* address); +extern struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port); +extern struct hub_link* link_connect_uri(struct hub_info* hub, const char* address); /** * Disconnect a link connection.