void prim_con_listener_port(PRIM_PROTOTYPE) { /* int -- int */ CHECKOP(1); oper1 = POP(); if (mlev < LMAGE) abort_interp("Mage prim"); if (oper1->type != PROG_INTEGER) abort_interp("Argument not an integer (1)"); result = oper1->data.number; if ((result < 1) || (result > pcount())) abort_interp("Invalid connection number (1)"); CHECKOFLOW(1); CLEAR(oper1); result = lport(result); PushInt(result); }
AnsiString SwitchP2P(CConceptClient *owner, char *host) { AnsiString result; is_p2p = 0; memset(&p2paddr, 0, sizeof(p2paddr)); p2paddr_len = 0; if (owner->RTSOCKET <= 0) return result; int s_len = strlen(host); if ((!owner) || (!host) || (!s_len)) return result; char *stun_server = host; char *p_str = strchr(host, ','); if ((!p_str) || (p_str[1] == '-')) return result; p_str[0] = 0; p_str++; char *local_host = strchr(p_str, ','); if ((!local_host) || (local_host[1] == '-')) return result; local_host[0] = 0; local_host++; char *local_port = strchr(local_host, ','); if ((!local_port) || (local_port[1] == '-')) return result; local_port[0] = 0; local_port++; AnsiString lport(local_port); struct addrinfo hints; struct addrinfo *a_res = 0; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; int gerr = getaddrinfo(local_host, local_port, &hints, &a_res); if ((gerr != 0) || (!a_res)) { AnsiString err((char *)"Error in getaddrinfo(): "); err += host; err += (char *)":"; err += p_str; err += (char *)" "; err += (char *)gai_strerror(gerr); fprintf(stderr, "Dropping RT socket\n"); result = ""; return result; } if ((a_res->ai_family != AF_INET) && (a_res->ai_family != AF_INET6)) { freeaddrinfo(a_res); fprintf(stderr, "Invalid socket family\n"); return result; } memcpy(&p2paddr, a_res->ai_addr, a_res->ai_addrlen); p2paddr_len = a_res->ai_addrlen; unsigned short connect_port = 0; char connect_ip[0xFF]; connect_ip[0] = 0; if (stun_server[0] == '*') { if (a_res->ai_family == AF_INET) { inet_ntop(a_res->ai_family, &((struct sockaddr_in *)&p2paddr)->sin_addr, connect_ip, INET6_ADDRSTRLEN + 1); connect_port = ntohs(((struct sockaddr_in *)&p2paddr)->sin_port); } else { inet_ntop(a_res->ai_family, &((struct sockaddr_in6 *)&p2paddr)->sin6_addr, connect_ip, INET6_ADDRSTRLEN + 1); connect_port = ntohs(((struct sockaddr_in6 *)&p2paddr)->sin6_port); } freeaddrinfo(a_res); } else { freeaddrinfo(a_res); int res = STUN(owner->RTSOCKET, stun_server, p_str, connect_ip, &connect_port); if (!res) return result; } result = connect_ip; result += (char *)","; result += AnsiString((long)connect_port); is_p2p = 1; if (lastaddr_len) { // already received hello package memcpy(&p2paddr, &lastaddr, lastaddr_len); p2paddr_len = lastaddr_len; memset(&lastaddr, 0, sizeof(lastaddr)); lastaddr_len = 0; is_p2p = 2; } sendto(owner->RTSOCKET, "hi", 2, 0, (struct sockaddr *)&p2paddr, p2paddr_len); sendto(owner->RTSOCKET, "hi", 2, 0, (struct sockaddr *)&p2paddr, p2paddr_len); sendto(owner->RTSOCKET, "hi", 2, 0, (struct sockaddr *)&p2paddr, p2paddr_len); return result; }
AnsiString InitUDP2(CConceptClient *owner, char *host) { AnsiString result; if (owner->RTSOCKET) { closesocket(owner->RTSOCKET); owner->RTSOCKET = INVALID_SOCKET; } int s_len = strlen(host); if ((!owner) || (!host) || (!s_len)) return result; char *stun_server = host; char *p_str = strchr(host, ','); if ((!p_str) || (p_str[1] == '-')) return result; p_str[0] = 0; p_str++; char *local_host = strchr(p_str, ','); if ((!local_host) || (local_host[1] == '-')) return result; local_host[0] = 0; local_host++; char *local_port = strchr(local_host, ','); if ((!local_port) || (local_port[1] == '-')) return result; local_port[0] = 0; local_port++; AnsiString lport(local_port); struct addrinfo hints; struct addrinfo *a_res = 0; memset(&serveraddr, 0, sizeof(serveraddr)); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; int gerr = getaddrinfo(local_host, local_port, &hints, &a_res); if ((gerr != 0) || (!a_res)) { AnsiString err((char *)"Error in getaddrinfo(): "); err += host; err += (char *)":"; err += p_str; err += (char *)" "; err += (char *)gai_strerror(gerr); fprintf(stderr, "Dropping RT socket: %s\n", err.c_str()); result = ""; return result; } if ((a_res->ai_family != AF_INET) && (a_res->ai_family != AF_INET6)) { freeaddrinfo(a_res); fprintf(stderr, "Invalid socket family\n"); return result; } memcpy(&serveraddr, a_res->ai_addr, a_res->ai_addrlen); server_len = a_res->ai_addrlen; unsigned short connect_port = 0; int socket = CreateUDPSocket(lport.ToInt(), a_res->ai_family == AF_INET6, connect_port); freeaddrinfo(a_res); if (socket < 0) return result; char connect_ip[0xFF]; connect_ip[0] = 0; if (stun_server[0] == '*') { strcpy(connect_ip, "self"); } else { int res = STUN(socket, stun_server, p_str, connect_ip, &connect_port); if (!res) { closesocket(socket); return result; } } owner->RTSOCKET = socket; result = connect_ip; result += (char *)","; result += AnsiString((long)connect_port); return result; }