mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
a bad version of UDP hole punching for local agents
This commit is contained in:
parent
b05909cf00
commit
d1433aa2bd
4 changed files with 111 additions and 56 deletions
|
@ -42,8 +42,10 @@ const int LOGOFF_CHECK_INTERVAL = 5000;
|
|||
struct AgentList {
|
||||
char agentType;
|
||||
uint32_t ip;
|
||||
in_addr sin_addr;
|
||||
in_port_t port;
|
||||
in_addr public_sin_addr;
|
||||
in_port_t public_port;
|
||||
char *private_addr;
|
||||
in_port_t private_port;
|
||||
float x, y, z;
|
||||
bool active;
|
||||
timeval time, connectTime;
|
||||
|
@ -61,11 +63,11 @@ double diffclock(timeval clock1,timeval clock2)
|
|||
return diffms;
|
||||
}
|
||||
|
||||
int addAgent(uint32_t ip, in_port_t port, char agentType, float x, float y, float z) {
|
||||
int addAgent(uint32_t ip, in_port_t port, char *private_ip, unsigned short private_port, char agentType, float x, float y, float z) {
|
||||
// Search for agent in list and add if needed
|
||||
int i = 0;
|
||||
int is_new = 0;
|
||||
while ((ip != agents[i].ip || port != agents[i].port) && (i < num_agents)) {
|
||||
while ((ip != agents[i].ip || port != agents[i].public_port) && (i < num_agents)) {
|
||||
i++;
|
||||
}
|
||||
if ((i == num_agents) || (agents[i].active == false)) is_new = 1;
|
||||
|
@ -74,8 +76,10 @@ int addAgent(uint32_t ip, in_port_t port, char agentType, float x, float y, floa
|
|||
agents[i].y = y;
|
||||
agents[i].z = z;
|
||||
agents[i].active = true;
|
||||
agents[i].sin_addr.s_addr = ip;
|
||||
agents[i].port = port;
|
||||
agents[i].public_sin_addr.s_addr = ip;
|
||||
agents[i].public_port = port;
|
||||
agents[i].private_addr = private_ip;
|
||||
agents[i].private_port = private_port;
|
||||
agents[i].agentType = agentType;
|
||||
gettimeofday(&agents[i].time, NULL);
|
||||
if (is_new) gettimeofday(&agents[i].connectTime, NULL);
|
||||
|
@ -92,7 +96,7 @@ void update_agent_list(timeval now) {
|
|||
if ((diffclock(agents[i].time, now) > LOGOFF_CHECK_INTERVAL) &&
|
||||
agents[i].active) {
|
||||
std::cout << "Expired Agent type " << agents[i].agentType << " from " <<
|
||||
inet_ntoa(agents[i].sin_addr) << ":" << agents[i].port << "\n";
|
||||
inet_ntoa(agents[i].public_sin_addr) << ":" << agents[i].public_port << "\n";
|
||||
agents[i].active = false;
|
||||
}
|
||||
}
|
||||
|
@ -102,8 +106,10 @@ void send_agent_list(sockaddr_in *agentAddrPointer) {
|
|||
int i, length = 0;
|
||||
ssize_t sentBytes;
|
||||
char buffer[MAX_PACKET_SIZE];
|
||||
char * address;
|
||||
char portstring[10];
|
||||
char * public_address;
|
||||
char public_portstring[10];
|
||||
char * private_address;
|
||||
char private_portstring[10];
|
||||
int numSent = 0;
|
||||
buffer[length++] = 'D';
|
||||
//std::cout << "send list to: " << inet_ntoa(dest_address->sin_addr) << "\n";
|
||||
|
@ -111,21 +117,31 @@ void send_agent_list(sockaddr_in *agentAddrPointer) {
|
|||
if (agents[i].active) {
|
||||
// Write the type of the agent
|
||||
buffer[length++] = agents[i].agentType;
|
||||
// Write agent's IP address
|
||||
address = inet_ntoa(agents[i].sin_addr);
|
||||
memcpy(&buffer[length], address, strlen(address));
|
||||
length += strlen(address);
|
||||
// Add port number
|
||||
// Write agent's public IP address
|
||||
public_address = inet_ntoa(agents[i].public_sin_addr);
|
||||
memcpy(&buffer[length], public_address, strlen(public_address));
|
||||
length += strlen(public_address);
|
||||
// Add public port number
|
||||
buffer[length++] = ' ';
|
||||
sprintf(portstring, "%d\n", agents[i].port);
|
||||
memcpy(&buffer[length], portstring, strlen(portstring));
|
||||
length += strlen(portstring);
|
||||
// Add comma separator between agents
|
||||
buffer[length++] = ',';
|
||||
sprintf(public_portstring, "%hd", agents[i].public_port);
|
||||
memcpy(&buffer[length], public_portstring, strlen(public_portstring));
|
||||
length += strlen(public_portstring);
|
||||
// Write agent's private IP address
|
||||
buffer[length++] = ' ';
|
||||
private_address = agents[i].private_addr;
|
||||
memcpy(&buffer[length], private_address, strlen(private_address));
|
||||
length += strlen(private_address);
|
||||
// Add private port number
|
||||
buffer[length++] = ' ';
|
||||
sprintf(private_portstring, "%hd,", agents[i].private_port);
|
||||
memcpy(&buffer[length], private_portstring, strlen(private_portstring));
|
||||
length += strlen(private_portstring);
|
||||
numSent++;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "The sent buffer was " << buffer << "\n";
|
||||
|
||||
if (length > 1) {
|
||||
sentBytes = domainSocket.send(agentAddrPointer, buffer, length);
|
||||
|
||||
|
@ -150,11 +166,14 @@ int main(int argc, const char * argv[])
|
|||
while (true) {
|
||||
if (domainSocket.receive(&agentAddress, packet_data, &receivedBytes)) {
|
||||
float x,y,z;
|
||||
char agentType;
|
||||
sscanf(packet_data, "%c %f,%f,%f", &agentType, &x, &y, &z);
|
||||
if (addAgent(agentAddress.sin_addr.s_addr, ntohs(agentAddress.sin_port), agentType, x, y, z)) {
|
||||
char agentType;
|
||||
char private_ip[50];
|
||||
unsigned short private_port;
|
||||
sscanf(packet_data, "%c %f,%f,%f,%s %hd", &agentType, &x, &y, &z, private_ip, &private_port);
|
||||
if (addAgent(agentAddress.sin_addr.s_addr, ntohs(agentAddress.sin_port), private_ip, private_port, agentType, x, y, z)) {
|
||||
std::cout << "Added Agent, type " << agentType << " from " <<
|
||||
inet_ntoa(agentAddress.sin_addr) << ":" << ntohs(agentAddress.sin_port) << "\n";
|
||||
inet_ntoa(agentAddress.sin_addr) << ":" << ntohs(agentAddress.sin_port) <<
|
||||
" (" << private_ip << ":" << private_port << ")" << "\n";
|
||||
}
|
||||
// Reply with packet listing nearby active agents
|
||||
send_agent_list(&agentAddress);
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
const int MAX_AGENTS = 100;
|
||||
struct AgentList {
|
||||
char address[255];
|
||||
unsigned short port;
|
||||
char public_address[255];
|
||||
unsigned short public_port;
|
||||
char private_address[255];
|
||||
unsigned short private_port;
|
||||
char *goodAddress = NULL;
|
||||
unsigned short goodPort;
|
||||
timeval pingStarted;
|
||||
int pingMsecs;
|
||||
char agentType;
|
||||
|
@ -29,7 +33,7 @@ int num_agents = 0;
|
|||
|
||||
|
||||
char * getAgentAddress(int agentNumber) {
|
||||
if (agentNumber < getAgentCount()) return agents[agentNumber].address;
|
||||
if (agentNumber < getAgentCount()) return agents[agentNumber].public_address;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
@ -51,17 +55,15 @@ int update_agents(char * data, int length) {
|
|||
std::string packet(data, length);
|
||||
size_t spot;
|
||||
size_t start_spot = 0;
|
||||
std::string address, port;
|
||||
char *public_address = new char[255];
|
||||
char *private_address = new char[255];
|
||||
char agentType;
|
||||
unsigned short nPort = 0;
|
||||
unsigned int iPort = 0;
|
||||
unsigned short public_port, private_port;
|
||||
spot = packet.find_first_of (",", 0);
|
||||
while (spot != std::string::npos) {
|
||||
std::string thisAgent = packet.substr(start_spot, spot-start_spot);
|
||||
//std::cout << "raw string: " << thisAgent << "\n";
|
||||
sscanf(thisAgent.c_str(), "%c %s %u", &agentType, address.c_str(), &iPort);
|
||||
nPort = (unsigned short) iPort;
|
||||
add_agent((char *)address.c_str(), nPort, agentType);
|
||||
sscanf(thisAgent.c_str(), "%c %s %hd %s %hd", &agentType, public_address, &public_port, private_address, &private_port);
|
||||
add_agent(public_address, public_port, private_address, private_port, agentType);
|
||||
numAgents++;
|
||||
start_spot = spot + 1;
|
||||
if (start_spot < packet.length())
|
||||
|
@ -91,7 +93,7 @@ void update_agent(char * address, unsigned short port, char * data, int length)
|
|||
{
|
||||
//printf("%s:%d\n", address, port);
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) {
|
||||
if ((strcmp(address, agents[i].public_address) == 0) && (agents[i].public_port == port)) {
|
||||
// Update the agent
|
||||
agents[i].head.recvBroadcastData(data, length);
|
||||
if ((strcmp(address, "127.0.0.1") == 0) && (port == AGENT_UDP_PORT)) {
|
||||
|
@ -104,21 +106,23 @@ void update_agent(char * address, unsigned short port, char * data, int length)
|
|||
//
|
||||
// Look for an agent by it's IP number, add if it does not exist in local list
|
||||
//
|
||||
int add_agent(char * address, unsigned short port, char agentType) {
|
||||
int add_agent(char * address, unsigned short port, char *private_address, unsigned short private_port, char agentType) {
|
||||
//std::cout << "Checking for " << IP->c_str() << " ";
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) {
|
||||
if ((strcmp(address, agents[i].public_address) == 0) && (agents[i].public_port == port)) {
|
||||
//std::cout << "Found agent!\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (num_agents < MAX_AGENTS) {
|
||||
strcpy(agents[num_agents].address, address);
|
||||
agents[num_agents].port = port;
|
||||
strcpy(agents[num_agents].public_address, address);
|
||||
agents[num_agents].public_port = port;
|
||||
agents[num_agents].agentType = agentType;
|
||||
strcpy(agents[num_agents].private_address, private_address);
|
||||
agents[num_agents].private_port = private_port;
|
||||
std::cout << "Added Agent # " << num_agents << " with Address " <<
|
||||
agents[num_agents].address << ":" << agents[num_agents].port << " T: " <<
|
||||
agentType << "\n";
|
||||
agents[num_agents].public_address << ":" << agents[num_agents].public_port << " T: " <<
|
||||
agentType << " (" << agents[num_agents].private_address << ":" << agents[num_agents].private_port << ")\n";
|
||||
|
||||
num_agents++;
|
||||
return 1;
|
||||
|
@ -134,19 +138,16 @@ int add_agent(char * address, unsigned short port, char agentType) {
|
|||
int broadcastToAgents(UDPSocket *handle, char * data, int length, int sendToSelf) {
|
||||
int sent_bytes;
|
||||
//printf("broadcasting to %d agents\n", num_agents);
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if (sendToSelf || (((strcmp((char *)"127.0.0.1", agents[i].address) != 0)
|
||||
&& (agents[i].port != AGENT_UDP_PORT))))
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if (agents[i].agentType != 'M' && agents[i].goodAddress != NULL) {
|
||||
// std::cout << "broadcasting my agent data to: " << agents[i].goodAddress << " : " << agents[i].goodPort << "\n";
|
||||
|
||||
if (agents[i].agentType != 'M') {
|
||||
//std::cout << "broadcasting my agent data to: " << agents[i].address << " : " << agents[i].port << "\n";
|
||||
|
||||
sent_bytes = handle->send(agents[i].address, agents[i].port, data, length);
|
||||
if (sent_bytes != length) {
|
||||
std::cout << "Broadcast to agents FAILED\n";
|
||||
return 0;
|
||||
}
|
||||
sent_bytes = handle->send(agents[i].goodAddress, agents[i].goodPort, data, length);
|
||||
if (sent_bytes != length) {
|
||||
std::cout << "Broadcast to agents FAILED\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -157,7 +158,12 @@ void pingAgents(UDPSocket *handle) {
|
|||
for (int i = 0; i < num_agents; i++) {
|
||||
if (agents[i].agentType != 'M') {
|
||||
gettimeofday(&agents[i].pingStarted, NULL);
|
||||
handle->send(agents[i].address, agents[i].port, payload, 1);
|
||||
if (agents[i].goodAddress == NULL) {
|
||||
handle->send(agents[i].public_address, agents[i].public_port, payload, 1);
|
||||
handle->send(agents[i].private_address, agents[i].private_port, payload, 1);
|
||||
} else {
|
||||
handle->send(agents[i].goodAddress, agents[i].goodPort, payload, 1);
|
||||
}
|
||||
//printf("\nSent Ping at %d usecs\n", agents[i].pingStarted.tv_usec);
|
||||
}
|
||||
|
||||
|
@ -167,7 +173,19 @@ void pingAgents(UDPSocket *handle) {
|
|||
// On receiving a ping reply, save that with the agent record
|
||||
void setAgentPing(char * address, unsigned short port) {
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) {
|
||||
bool isLocal = false;
|
||||
bool isPublic = false;
|
||||
if ((strcmp(address, agents[i].public_address) == 0) && (agents[i].public_port == port)) {
|
||||
isPublic = true;
|
||||
agents[i].goodAddress = agents[i].public_address;
|
||||
agents[i].goodPort = agents[i].public_port;
|
||||
} else if ((strcmp(address, agents[i].private_address) == 0) && (agents[i].private_port == port)) {
|
||||
isLocal = true;
|
||||
agents[i].goodAddress = agents[i].private_address;
|
||||
agents[i].goodPort = agents[i].private_port;
|
||||
}
|
||||
|
||||
if (isPublic || isLocal) {
|
||||
timeval pingReceived;
|
||||
gettimeofday(&pingReceived, NULL);
|
||||
float pingMsecs = diffclock(&agents[i].pingStarted, &pingReceived);
|
||||
|
@ -180,7 +198,7 @@ void setAgentPing(char * address, unsigned short port) {
|
|||
void kludgyMixerUpdate(Audio audio) {
|
||||
for (int i = 0; i < num_agents; i++) {
|
||||
if (agents[i].agentType == 'M') {
|
||||
audio.updateMixerParams(agents[i].address, agents[i].port);
|
||||
audio.updateMixerParams(agents[i].public_address, agents[i].public_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
const int AGENT_UDP_PORT = 40103;
|
||||
|
||||
int update_agents(char * data, int length);
|
||||
int add_agent(char * address, unsigned short port, char agentType);
|
||||
int add_agent(char * address, unsigned short port, char *private_address, unsigned short private_port, char agentType);
|
||||
int broadcastToAgents(UDPSocket * handle, char * data, int length, int sendToSelf);
|
||||
void pingAgents(UDPSocket *handle);
|
||||
void setAgentPing(char * address, unsigned short port);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
// These includes are for the serial port reading/writing
|
||||
#include <unistd.h>
|
||||
|
@ -82,6 +83,8 @@ int WIDTH = 1200;
|
|||
int HEIGHT = 800;
|
||||
int fullscreen = 0;
|
||||
|
||||
char localAddressBuffer[INET_ADDRSTRLEN];
|
||||
|
||||
Oscilloscope audioScope(512,200,true);
|
||||
|
||||
#define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you
|
||||
|
@ -228,7 +231,8 @@ void Timer(int extra)
|
|||
// Send a message to the domainserver telling it we are ALIVE
|
||||
//
|
||||
char output[100];
|
||||
sprintf(output, "%c %f,%f,%f", 'I', location[0], location[1], location[2]);
|
||||
sprintf(output, "%c %f,%f,%f,%s %hd", 'I', location[0], location[1], location[2], localAddressBuffer, (unsigned short) AGENT_UDP_PORT);
|
||||
std::cout << "sending " << output << " to domain server\n";
|
||||
int packet_size = strlen(output);
|
||||
agentSocket.send(DOMAIN_IP, DOMAINSERVER_PORT, output, packet_size);
|
||||
|
||||
|
@ -929,6 +933,20 @@ int main(int argc, char** argv)
|
|||
// Create network socket and buffer
|
||||
incomingPacket = new char[MAX_PACKET_SIZE];
|
||||
|
||||
struct ifaddrs * ifAddrStruct=NULL;
|
||||
struct ifaddrs * ifa=NULL;
|
||||
void * tmpAddrPtr=NULL;
|
||||
|
||||
getifaddrs(&ifAddrStruct);
|
||||
|
||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
|
||||
// is a valid IP4 Address
|
||||
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
|
||||
inet_ntop(AF_INET, tmpAddrPtr, localAddressBuffer, INET_ADDRSTRLEN);
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup the IP address of things we have hostnames
|
||||
if (atoi(DOMAIN_IP) == 0) {
|
||||
struct hostent* pHostInfo;
|
||||
|
|
Loading…
Reference in a new issue