static void refresh_peer_server(int sock, PeerServer * ps) { unsigned i; const char * transport = peer_server_getprop(ps, "TransportName", NULL); assert(transport != NULL); if (strcmp(transport, "UNIX") == 0) { char str_id[64]; PeerServer * ps2 = peer_server_alloc(); ps2->flags = ps->flags | PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE; for (i = 0; i < ps->ind; i++) { peer_server_addprop(ps2, loc_strdup(ps->list[i].name), loc_strdup(ps->list[i].value)); } snprintf(str_id, sizeof(str_id), "%s:%s", transport, peer_server_getprop(ps, "Host", "")); for (i = 0; str_id[i]; i++) { /* Character '/' is prohibited in a peer ID string */ if (str_id[i] == '/') str_id[i] = '|'; } peer_server_addprop(ps2, loc_strdup("ID"), loc_strdup(str_id)); peer_server_add(ps2, PEER_DATA_RETENTION_PERIOD * 2); } else { struct sockaddr_in sin; #if defined(_WRS_KERNEL) int sinlen; #else socklen_t sinlen; #endif const char *str_port = peer_server_getprop(ps, "Port", NULL); int ifcind; struct in_addr src_addr; ip_ifc_info ifclist[MAX_IFC]; sinlen = sizeof sin; if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != 0) { trace(LOG_ALWAYS, "refresh_peer_server: getsockname error: %s", errno_to_str(errno)); return; } ifcind = build_ifclist(sock, MAX_IFC, ifclist); while (ifcind-- > 0) { char str_host[64]; char str_id[64]; PeerServer * ps2; if (sin.sin_addr.s_addr != INADDR_ANY && (ifclist[ifcind].addr & ifclist[ifcind].mask) != (sin.sin_addr.s_addr & ifclist[ifcind].mask)) { continue; } src_addr.s_addr = ifclist[ifcind].addr; ps2 = peer_server_alloc(); ps2->flags = ps->flags | PS_FLAG_LOCAL | PS_FLAG_DISCOVERABLE; for (i = 0; i < ps->ind; i++) { peer_server_addprop(ps2, loc_strdup(ps->list[i].name), loc_strdup(ps->list[i].value)); } inet_ntop(AF_INET, &src_addr, str_host, sizeof(str_host)); snprintf(str_id, sizeof(str_id), "%s:%s:%s", transport, str_host, str_port); peer_server_addprop(ps2, loc_strdup("ID"), loc_strdup(str_id)); peer_server_addprop(ps2, loc_strdup("Host"), loc_strdup(str_host)); peer_server_addprop(ps2, loc_strdup("Port"), loc_strdup(str_port)); peer_server_add(ps2, PEER_DATA_RETENTION_PERIOD * 2); } } }
static int lua_peer_getvalue(lua_State *L) { struct peer_extra *pse = NULL; const char *s; assert(L == luastate); if(lua_gettop(L) != 2 || (pse = lua2peer(L, 1)) == NULL || !lua_isstring(L, 2)) { luaL_error(L, "wrong number or type of arguments"); } if(pse->ps == NULL) luaL_error(L, "stale peer"); trace(LOG_LUA, "lua_peer_getvalue %p", pse->ps); if((s = peer_server_getprop(pse->ps, lua_tostring(L, 2), NULL)) == NULL) { lua_pushnil(L); return 1; } lua_pushstring(L, s); return 1; }
void channel_np_connect(PeerServer * ps, ChannelConnectCallBack callback, void * callback_args) { const char * host = peer_server_getprop(ps, "Host", NULL); const char * port = peer_server_getprop(ps, "Port", NULL); const char * get_url = peer_server_getprop(ps, "GetUrl", NULL); const char * host_name = peer_server_getprop(ps, "HostName", NULL); #if ENABLE_WebSocket_SOCKS_V5 const char * proxy = peer_server_getprop(ps, "Proxy", NULL); #endif ChannelConnectInfo * info = NULL; char port_str[16]; struct addrinfo hints; struct addrinfo * reslist = NULL; int error; ini_nopoll(); if (port == NULL) { sprintf(port_str, "%d", DISCOVERY_TCF_PORT); port = port_str; } memset(&hints, 0, sizeof hints); hints.ai_family = PF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; error = loc_getaddrinfo(host, port, &hints, &reslist); if (error) error = set_gai_errno(error); if (!error) { struct addrinfo * res; info = (ChannelConnectInfo *)loc_alloc_zero(sizeof(ChannelConnectInfo)); for (res = reslist; res != NULL; res = res->ai_next) { info->addr_len = res->ai_addrlen; info->addr_buf = (struct sockaddr *)loc_alloc(res->ai_addrlen); memcpy(info->addr_buf, res->ai_addr, res->ai_addrlen); error = 0; break; } loc_freeaddrinfo(reslist); } if (!error && info->addr_buf == NULL) error = ENOENT; if (error) { if (info != NULL) { loc_free(info->addr_buf); loc_free(info); } callback(callback_args, error, NULL); } else { noPollCtx * np_ctx_client; np_ctx_client = nopoll_ctx_new(); /*nopoll_log_enable(np_ctx_client, nopoll_true);*/ #if ENABLE_WebSocket_SOCKS_V5 if (proxy != NULL) { /* save global proxy values */ char * proxy_host = socks_v5_host; char * proxy_port = socks_v5_port; if (parse_socks_v5_proxy(proxy) != 0) { socks_v5_host = proxy_host; socks_v5_port = proxy_port; if (info != NULL) { loc_free(info->addr_buf); loc_free(info); } callback(callback_args, errno, NULL); return; } if (socks_v5_host != NULL) nopoll_conn_set_socks_v5_proxy(np_ctx_client, socks_v5_host, socks_v5_port); /* Restore global proxy values */ socks_v5_host = proxy_host; socks_v5_port = proxy_port; } #endif info->callback = callback; info->callback_args = callback_args; info->is_ssl = strcmp(peer_server_getprop(ps, "TransportName", ""), "WSS") == 0; info->req.client_data = info; info->req.done = channel_np_connect_done; info->req.type = AsyncReqUser; info->req.u.user.func = np_wt_connect; info->req.u.user.data = info; info->host = loc_strdup(host == NULL ? "127.0.0.1" : host); info->port = loc_strdup(port); info->get_url = get_url; info->host_name = host_name; info->np_ctx = np_ctx_client; async_req_post(&info->req); } }
ChannelServer * channel_np_server(PeerServer * ps) { /* const char * host = peer_server_getprop(ps, "Host", NULL);*/ const char * port = peer_server_getprop(ps, "Port", NULL); char port_str[16]; const char * host = peer_server_getprop(ps, "Host", NULL); const char * certificate = peer_server_getprop(ps, "CertificateFile", NULL); const char * key = peer_server_getprop(ps, "KeyFile", NULL); noPollCtx * np_ctx; noPollConn * np_listener; int ssl; assert(is_dispatch_thread()); if (port == NULL) { sprintf(port_str, "%d", DISCOVERY_TCF_PORT); port = port_str; } ini_nopoll(); /* create the nopoll ctx */ np_ctx = nopoll_ctx_new (); if(np_ctx == NULL) { trace(LOG_ALWAYS, "Unable to create nopoll context: %s", errno_to_str(errno)); return NULL; } /*nopoll_log_enable(np_ctx, nopoll_true);*/ ssl = strcmp(peer_server_getprop(ps, "TransportName", ""), "WSS") == 0; if (ssl) np_listener = nopoll_listener_tls_new (np_ctx, host == NULL ? "0.0.0.0" : host, port); else np_listener = nopoll_listener_new (np_ctx, host == NULL ? "0.0.0.0" : host, port); if (np_listener == NULL) { trace(LOG_ALWAYS, "Unable to create nopoll listener: %s", errno_to_str(errno)); nopoll_ctx_unref(np_ctx); return NULL; } /* configure certificates to be used by this listener */ if (ssl) { errno = 0; if (! nopoll_listener_set_certificate (np_listener, certificate, key, NULL)) { printf ("ERROR: unable to configure certificates for TLS websocket..\n"); if (errno == 0) errno = EINVAL; nopoll_conn_close (np_listener); nopoll_ctx_unref(np_ctx); return NULL; } /* register certificates at context level */ errno = 0; if (! nopoll_ctx_set_certificate (np_ctx, NULL, certificate, key, NULL)) { printf ("ERROR: unable to setup certificates at context level..\n"); if (errno == 0) errno = EINVAL; nopoll_conn_close (np_listener); nopoll_ctx_unref(np_ctx); return NULL; } } peer_server_addprop(ps, loc_strdup("Port"), loc_strdup(port)); return channel_server_create(ps, np_ctx, np_listener, ssl); }