mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
hook domain server up to AgentList, pack sockets
This commit is contained in:
parent
7205817476
commit
c57380012e
8 changed files with 133 additions and 199 deletions
|
@ -27,167 +27,55 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#include "AgentList.h"
|
||||
|
||||
const int DOMAIN_LISTEN_PORT = 40102;
|
||||
const char DESTINATION_IP[] = "127.0.0.1";
|
||||
|
||||
const int MAX_PACKET_SIZE = 1500;
|
||||
char packet_data[MAX_PACKET_SIZE];
|
||||
unsigned char packetData[MAX_PACKET_SIZE];
|
||||
|
||||
const int MAX_AGENTS = 1000;
|
||||
const int LOGOFF_CHECK_INTERVAL = 5000;
|
||||
|
||||
struct AgentList {
|
||||
char agentType;
|
||||
uint32_t ip;
|
||||
in_addr public_sin_addr;
|
||||
unsigned short public_port;
|
||||
char *private_addr;
|
||||
unsigned short private_port;
|
||||
float x, y, z;
|
||||
bool active;
|
||||
timeval time, connectTime;
|
||||
} agents[MAX_AGENTS];
|
||||
|
||||
int num_agents = 0;
|
||||
int lastActiveCount = 0;
|
||||
AgentList agentList(DOMAIN_LISTEN_PORT);
|
||||
|
||||
UDPSocket domainSocket = UDPSocket(DOMAIN_LISTEN_PORT);
|
||||
|
||||
double diffclock(timeval clock1,timeval clock2)
|
||||
{
|
||||
double diffms = (clock2.tv_sec - clock1.tv_sec) * 1000.0;
|
||||
diffms += (clock2.tv_usec - clock1.tv_usec) / 1000.0; // us to ms
|
||||
return diffms;
|
||||
}
|
||||
|
||||
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].public_port) && (i < num_agents)) {
|
||||
i++;
|
||||
}
|
||||
int listForBroadcast(unsigned char *listBuffer) {
|
||||
unsigned char *currentBufferPos = listBuffer + 1;
|
||||
unsigned char *startPointer = currentBufferPos;
|
||||
|
||||
if ((i == num_agents) || (agents[i].active == false)) {
|
||||
is_new = 1;
|
||||
agents[i].private_addr = new char[255];
|
||||
}
|
||||
|
||||
agents[i].ip = ip;
|
||||
agents[i].x = x;
|
||||
agents[i].y = y;
|
||||
agents[i].z = z;
|
||||
agents[i].active = true;
|
||||
agents[i].public_sin_addr.s_addr = ip;
|
||||
agents[i].public_port = port;
|
||||
strcpy(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);
|
||||
if (i == num_agents) {
|
||||
num_agents++;
|
||||
}
|
||||
return is_new;
|
||||
}
|
||||
|
||||
void update_agent_list(timeval now) {
|
||||
int i;
|
||||
//std::cout << "Checking agent list" << "\n";
|
||||
for (i = 0; i < num_agents; i++) {
|
||||
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].public_sin_addr) << ":" << agents[i].public_port << "\n";
|
||||
agents[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_agent_list(sockaddr_in *agentAddrPointer) {
|
||||
int i, length = 0;
|
||||
ssize_t sentBytes;
|
||||
char buffer[MAX_PACKET_SIZE];
|
||||
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";
|
||||
for (i = 0; i < num_agents; i++) {
|
||||
if (agents[i].active) {
|
||||
// Write the type of the agent
|
||||
buffer[length++] = agents[i].agentType;
|
||||
// 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(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);
|
||||
for(std::vector<Agent>::iterator agent = agentList.agents.begin(); agent != agentList.agents.end(); agent++) {
|
||||
*currentBufferPos++ = agent->type;
|
||||
|
||||
if (sentBytes < length)
|
||||
std::cout << "Error sending agent list!\n";
|
||||
else if (numSent != lastActiveCount) {
|
||||
std::cout << numSent << " Active Agents\n";
|
||||
lastActiveCount = numSent;
|
||||
}
|
||||
currentBufferPos += packSocket(currentBufferPos, agent->publicSocket);
|
||||
currentBufferPos += packSocket(currentBufferPos, agent->localSocket);
|
||||
}
|
||||
|
||||
return 1 + (currentBufferPos - startPointer); // 1 is added for the leading 'D'
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
ssize_t receivedBytes = 0;
|
||||
timeval time, last_time;
|
||||
sockaddr_in agentAddress;
|
||||
char agentType;
|
||||
unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE];
|
||||
*broadcastPacket = 'D';
|
||||
|
||||
gettimeofday(&last_time, NULL);
|
||||
sockaddr_in agentPublicAddress, agentLocalAddress;
|
||||
agentLocalAddress.sin_family = AF_INET;
|
||||
|
||||
|
||||
while (true) {
|
||||
if (domainSocket.receive(&agentAddress, packet_data, &receivedBytes)) {
|
||||
float 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) <<
|
||||
" (" << private_ip << ":" << private_port << ")" << "\n";
|
||||
if (agentList.getAgentSocket()->receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
|
||||
agentType = packetData[0];
|
||||
unpackSocket(&packetData[1], (sockaddr *)&agentLocalAddress);
|
||||
|
||||
agentList.addOrUpdateAgent((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType);
|
||||
|
||||
int listBytes = listForBroadcast(broadcastPacket);
|
||||
|
||||
if (listBytes > 0) {
|
||||
agentList.getAgentSocket()->send((sockaddr *)&agentPublicAddress, broadcastPacket, listBytes);
|
||||
}
|
||||
// Reply with packet listing nearby active agents
|
||||
send_agent_list(&agentAddress);
|
||||
}
|
||||
|
||||
gettimeofday(&time, NULL);
|
||||
if (diffclock(last_time, time) > LOGOFF_CHECK_INTERVAL) {
|
||||
gettimeofday(&last_time, NULL);
|
||||
update_agent_list(last_time);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -55,14 +55,12 @@ int simulate_on = 1;
|
|||
|
||||
const int MAX_PACKET_SIZE = 1500;
|
||||
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
|
||||
char DOMAIN_IP[100] = ""; // IP Address will be used first if not empty string
|
||||
char DOMAIN_IP[100] = "192.168.1.47"; // IP Address will be used first if not empty string
|
||||
const int DOMAINSERVER_PORT = 40102;
|
||||
|
||||
AgentList agentList;
|
||||
|
||||
// For testing, add milliseconds of delay for received UDP packets
|
||||
char* incomingPacket;
|
||||
|
||||
int packetcount = 0;
|
||||
int packets_per_second = 0;
|
||||
int bytes_per_second = 0;
|
||||
|
@ -79,7 +77,7 @@ int WIDTH = 1200;
|
|||
int HEIGHT = 800;
|
||||
int fullscreen = 0;
|
||||
|
||||
char localAddressBuffer[INET_ADDRSTRLEN];
|
||||
in_addr_t localAddress;
|
||||
|
||||
Oscilloscope audioScope(512,200,true);
|
||||
|
||||
|
@ -222,11 +220,11 @@ void Timer(int extra)
|
|||
//
|
||||
// Send a message to the domainserver telling it we are ALIVE
|
||||
//
|
||||
char output[100];
|
||||
sprintf(output, "%c %f,%f,%f,%s %hd", 'I', location[0], location[1], location[2], localAddressBuffer, AGENT_SOCKET_LISTEN_PORT);
|
||||
std::cout << "sending " << output << " to domain server\n";
|
||||
int packet_size = strlen(output);
|
||||
agentList.getAgentSocket()->send(DOMAIN_IP, DOMAINSERVER_PORT, output, packet_size);
|
||||
unsigned char output[7];
|
||||
output[0] = 'I';
|
||||
packSocket(output + 1, localAddress, htons(AGENT_SOCKET_LISTEN_PORT));
|
||||
|
||||
agentList.getAgentSocket()->send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
||||
|
||||
// Ping the agents we can see
|
||||
agentList.pingAgents();
|
||||
|
@ -764,8 +762,10 @@ void *networkReceive(void *args)
|
|||
{
|
||||
sockaddr senderAddress;
|
||||
ssize_t bytesReceived;
|
||||
unsigned char *incomingPacket = new unsigned char[MAX_PACKET_SIZE];
|
||||
|
||||
while (true) {
|
||||
if (agentList.getAgentSocket()->receive(&senderAddress, (void *)incomingPacket, &bytesReceived)) {
|
||||
if (agentList.getAgentSocket()->receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||
packetcount++;
|
||||
bytescount += bytesReceived;
|
||||
|
||||
|
@ -926,20 +926,15 @@ void *poll_marker_capture(void *threadarg){
|
|||
|
||||
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);
|
||||
localAddress = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,4 +77,14 @@ bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, cha
|
|||
return type == otherAgentType
|
||||
&& socketMatch(publicSocket, otherPublicSocket)
|
||||
&& socketMatch(localSocket, otherLocalSocket);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Agent* agent) {
|
||||
sockaddr_in *agentPublicSocket = (sockaddr_in *)agent->publicSocket;
|
||||
sockaddr_in *agentLocalSocket = (sockaddr_in *)agent->localSocket;
|
||||
|
||||
os << "T: " << agent->type << " PA: " << inet_ntoa(agentPublicSocket->sin_addr) <<
|
||||
":" << ntohs(agentPublicSocket->sin_port) << " LA: " << inet_ntoa(agentLocalSocket->sin_addr) <<
|
||||
":" << ntohs(agentLocalSocket->sin_port);
|
||||
return os;
|
||||
}
|
|
@ -21,16 +21,21 @@ class Agent {
|
|||
Agent& operator=(Agent otherAgent);
|
||||
bool operator==(const Agent& otherAgent);
|
||||
~Agent();
|
||||
|
||||
|
||||
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
||||
|
||||
sockaddr *publicSocket, *localSocket, *activeSocket;
|
||||
char type;
|
||||
timeval pingStarted;
|
||||
int pingMsecs;
|
||||
bool isSelf;
|
||||
AgentData *linkedData;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const Agent* agent);
|
||||
private:
|
||||
void swap(Agent &first, Agent &second);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Agent* agent);
|
||||
|
||||
#endif /* defined(__hifi__Agent__) */
|
||||
|
|
|
@ -7,21 +7,26 @@
|
|||
//
|
||||
|
||||
#include "AgentList.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
AgentList::AgentList() : agentSocket(AGENT_SOCKET_LISTEN_PORT) {
|
||||
|
||||
}
|
||||
|
||||
AgentList::AgentList(int socketListenPort) : agentSocket(socketListenPort) {
|
||||
|
||||
}
|
||||
|
||||
UDPSocket * AgentList::getAgentSocket() {
|
||||
return &agentSocket;
|
||||
}
|
||||
|
||||
void AgentList::processAgentData(sockaddr *senderAddress, char *packetData, size_t dataBytes) {
|
||||
void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
|
||||
switch (packetData[0]) {
|
||||
case 'D':
|
||||
{
|
||||
// list of agents from domain server
|
||||
updateList(packetData);
|
||||
updateList(packetData, dataBytes);
|
||||
break;
|
||||
}
|
||||
case 'P':
|
||||
|
@ -40,52 +45,54 @@ void AgentList::processAgentData(sockaddr *senderAddress, char *packetData, size
|
|||
}
|
||||
}
|
||||
|
||||
int AgentList::updateList(char *packetData) {
|
||||
int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
||||
int readAgents = 0;
|
||||
int scannedItems = 0;
|
||||
|
||||
|
||||
char agentType;
|
||||
|
||||
// assumes only IPv4 addresses
|
||||
sockaddr_in *agentPublicSocket = new sockaddr_in;
|
||||
agentPublicSocket->sin_family = AF_INET;
|
||||
sockaddr_in *agentLocalSocket = new sockaddr_in;
|
||||
agentLocalSocket->sin_family = AF_INET;
|
||||
sockaddr_in agentPublicSocket;
|
||||
agentPublicSocket.sin_family = AF_INET;
|
||||
sockaddr_in agentLocalSocket;
|
||||
agentLocalSocket.sin_family = AF_INET;
|
||||
|
||||
unsigned char *readPtr = packetData + 1;
|
||||
unsigned char *startPtr = packetData;
|
||||
|
||||
Agent newAgent;
|
||||
|
||||
while((scannedItems = sscanf(packetData,
|
||||
"%c %u %hd %u %hd,",
|
||||
&agentType,
|
||||
&agentPublicSocket->sin_addr.s_addr,
|
||||
&agentPublicSocket->sin_port,
|
||||
&agentLocalSocket->sin_addr.s_addr,
|
||||
&agentLocalSocket->sin_port
|
||||
))) {
|
||||
while((readPtr - startPtr) < dataBytes) {
|
||||
agentType = *readPtr++;
|
||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentPublicSocket);
|
||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentLocalSocket);
|
||||
|
||||
std::vector<Agent>::iterator agent;
|
||||
|
||||
for(agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->matches((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType)) {
|
||||
// we already have this agent, stop checking
|
||||
break;
|
||||
}
|
||||
addOrUpdateAgent((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType);
|
||||
}
|
||||
|
||||
return readAgents;
|
||||
}
|
||||
|
||||
bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType) {
|
||||
std::vector<Agent>::iterator agent;
|
||||
|
||||
for(agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->matches(publicSocket, localSocket, agentType)) {
|
||||
// we already have this agent, stop checking
|
||||
break;
|
||||
}
|
||||
|
||||
if (agent == agents.end()) {
|
||||
// we didn't have this agent, so add them
|
||||
newAgent = Agent((sockaddr *)agentPublicSocket, (sockaddr *)agentLocalSocket, agentType);
|
||||
std::cout << "Added new agent - PS: " << agentPublicSocket << " LS: " << agentLocalSocket << " AT: " << agentType << "\n";
|
||||
agents.push_back(newAgent);
|
||||
} else {
|
||||
// we had this agent already, don't do anything
|
||||
}
|
||||
|
||||
readAgents++;
|
||||
}
|
||||
|
||||
return readAgents;
|
||||
if (agent == agents.end()) {
|
||||
// we didn't have this agent, so add them
|
||||
Agent newAgent = Agent(publicSocket, localSocket, agentType);
|
||||
|
||||
std::cout << "Added agent - " << &newAgent << "\n";
|
||||
|
||||
agents.push_back(newAgent);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// we had this agent already
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AgentList::pingAgents() {
|
||||
|
|
|
@ -19,16 +19,19 @@ const unsigned short AGENT_SOCKET_LISTEN_PORT = 40103;
|
|||
class AgentList {
|
||||
public:
|
||||
AgentList();
|
||||
AgentList(int socketListenPort);
|
||||
std::vector<Agent> agents;
|
||||
int updateList(char *packetData);
|
||||
void processAgentData(sockaddr *senderAddress, char *packetData, size_t dataBytes);
|
||||
|
||||
int broadcastToAgents(char *broadcastData, size_t dataBytes, bool sendToSelf);
|
||||
void pingAgents();
|
||||
UDPSocket* getAgentSocket();
|
||||
|
||||
int updateList(unsigned char *packetData, size_t dataBytes);
|
||||
bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType);
|
||||
void processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes);
|
||||
void broadcastToAgents(char *broadcastData, size_t dataBytes, bool sendToSelf);
|
||||
void pingAgents();
|
||||
private:
|
||||
UDPSocket agentSocket;
|
||||
int addAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType);
|
||||
|
||||
void handlePingReply(sockaddr *agentAddress);
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,29 @@ bool socketMatch(sockaddr *first, sockaddr *second) {
|
|||
}
|
||||
}
|
||||
|
||||
int packSocket(unsigned char *packStore, in_addr_t inAddress, in_port_t networkOrderPort) {
|
||||
packStore[0] = inAddress >> 24;
|
||||
packStore[1] = inAddress >> 16;
|
||||
packStore[2] = inAddress >> 8;
|
||||
packStore[3] = inAddress;
|
||||
|
||||
packStore[4] = networkOrderPort >> 8;
|
||||
packStore[5] = networkOrderPort;
|
||||
|
||||
return 6; // could be dynamically more if we need IPv6
|
||||
}
|
||||
|
||||
int packSocket(unsigned char *packStore, sockaddr *socketToPack) {
|
||||
return packSocket(packStore, ((sockaddr_in *) socketToPack)->sin_addr.s_addr, ((sockaddr_in *) socketToPack)->sin_port);
|
||||
}
|
||||
|
||||
int unpackSocket(unsigned char *packedData, sockaddr *unpackDestSocket) {
|
||||
sockaddr_in *destinationSocket = (sockaddr_in *) unpackDestSocket;
|
||||
destinationSocket->sin_addr.s_addr = (packedData[0] << 24) + (packedData[1] << 16) + (packedData[2] << 8) + packedData[3];
|
||||
destinationSocket->sin_port = (packedData[4] << 8) + packedData[5];
|
||||
return 6; // this could be more if we ever need IPv6
|
||||
}
|
||||
|
||||
UDPSocket::UDPSocket(int listeningPort) {
|
||||
// create the socket
|
||||
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
|
|
@ -28,5 +28,8 @@ class UDPSocket {
|
|||
};
|
||||
|
||||
bool socketMatch(sockaddr *first, sockaddr *second);
|
||||
int packSocket(unsigned char *packStore, in_addr_t inAddress, in_port_t networkOrderPort);
|
||||
int packSocket(unsigned char *packStore, sockaddr *socketToPack);
|
||||
int unpackSocket(unsigned char *packedData, sockaddr *unpackDestSocket);
|
||||
|
||||
#endif /* defined(__interface__UDPSocket__) */
|
||||
|
|
Loading…
Reference in a new issue