mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
remove AgentSocket abstraction to use sockaddr struct
This commit is contained in:
parent
42927ec602
commit
7205817476
9 changed files with 169 additions and 160 deletions
|
@ -762,54 +762,57 @@ void key(unsigned char k, int x, int y)
|
|||
//
|
||||
void *networkReceive(void *args)
|
||||
{
|
||||
sockaddr_in senderAddress;
|
||||
sockaddr senderAddress;
|
||||
ssize_t bytesReceived;
|
||||
while (true) {
|
||||
if (agentList.getAgentSocket()->receive(&senderAddress, (void *)incomingPacket, &bytesReceived)) {
|
||||
|
||||
packetcount++;
|
||||
bytescount += bytesReceived;
|
||||
// If packet is a Mouse data packet, copy it over
|
||||
if (incomingPacket[0] == 'P') {
|
||||
//
|
||||
// Got Ping, reply immediately!
|
||||
//
|
||||
//printf("Replying to ping!\n");
|
||||
char reply[] = "R";
|
||||
// agentSocket.send(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), reply, 1);
|
||||
} else if (incomingPacket[0] == 'R') {
|
||||
//
|
||||
// Got Reply, record as appropriate
|
||||
//
|
||||
// setAgentPing(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port));
|
||||
|
||||
} else if (incomingPacket[0] == 'M') {
|
||||
//
|
||||
// mouse location packet
|
||||
//
|
||||
sscanf(incomingPacket, "M %d %d", &target_x, &target_y);
|
||||
target_display = 1;
|
||||
//printf("X = %d Y = %d\n", target_x, target_y);
|
||||
} else if (incomingPacket[0] == 'D') {
|
||||
//
|
||||
// Message from domainserver
|
||||
//
|
||||
//printf("agent list received!\n");
|
||||
nearbyAgents = agentList.updateList(&incomingPacket[1]);
|
||||
std::cout << "Received " << nearbyAgents << " from DS!\n";
|
||||
// kludgyMixerUpdate(audio);
|
||||
} else if (incomingPacket[0] == 'H') {
|
||||
//
|
||||
// Broadcast packet from another agent
|
||||
//
|
||||
//printf("broadcast received");
|
||||
// update_agent(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), &incomingPacket[1], bytesReceived - 1);
|
||||
} else if (incomingPacket[0] == 'T') {
|
||||
// Received a self-test packet (to get one's own IP), copy it to local variable!
|
||||
// printf("My Address: %s:%u\n",
|
||||
// inet_ntoa(senderAddress.sin_addr),
|
||||
// senderAddress.sin_port);
|
||||
}
|
||||
|
||||
agentList.processAgentData(&senderAddress, incomingPacket, bytesReceived);
|
||||
|
||||
|
||||
// // If packet is a Mouse data packet, copy it over
|
||||
// if (incomingPacket[0] == 'P') {
|
||||
// //
|
||||
// // Got Ping, reply immediately!
|
||||
// //
|
||||
// //printf("Replying to ping!\n");
|
||||
// char reply[] = "R";
|
||||
// agentList.getAgentSocket()->send(&senderAddress, reply, 1);
|
||||
// } else if (incomingPacket[0] == 'R') {
|
||||
// //
|
||||
// // Got Reply, record as appropriate
|
||||
// //
|
||||
//// setAgentPing(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port));
|
||||
//
|
||||
// } else if (incomingPacket[0] == 'M') {
|
||||
// //
|
||||
// // mouse location packet
|
||||
// //
|
||||
// sscanf(incomingPacket, "M %d %d", &target_x, &target_y);
|
||||
// target_display = 1;
|
||||
// //printf("X = %d Y = %d\n", target_x, target_y);
|
||||
// } else if (incomingPacket[0] == 'D') {
|
||||
// //
|
||||
// // Message from domainserver
|
||||
// //
|
||||
// //printf("agent list received!\n");
|
||||
// nearbyAgents = agentList.updateList(&incomingPacket[1]);
|
||||
// std::cout << "Received " << nearbyAgents << " from DS!\n";
|
||||
//// kludgyMixerUpdate(audio);
|
||||
// } else if (incomingPacket[0] == 'H') {
|
||||
// //
|
||||
// // Broadcast packet from another agent
|
||||
// //
|
||||
// //printf("broadcast received");
|
||||
//// update_agent(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), &incomingPacket[1], bytesReceived - 1);
|
||||
// } else if (incomingPacket[0] == 'T') {
|
||||
// // Received a self-test packet (to get one's own IP), copy it to local variable!
|
||||
//// printf("My Address: %s:%u\n",
|
||||
//// inet_ntoa(senderAddress.sin_addr),
|
||||
//// senderAddress.sin_port);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,23 +7,32 @@
|
|||
//
|
||||
|
||||
#include "Agent.h"
|
||||
#include <arpa/inet.h>
|
||||
#include "UDPSocket.h"
|
||||
|
||||
Agent::Agent() {
|
||||
|
||||
}
|
||||
|
||||
Agent::Agent(AgentSocket *agentPublicSocket, AgentSocket *agentLocalSocket, char agentType) {
|
||||
publicSocket = new AgentSocket(*agentPublicSocket);
|
||||
localSocket = new AgentSocket(*agentLocalSocket);
|
||||
activeSocket = NULL;
|
||||
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType) {
|
||||
publicSocket = new sockaddr;
|
||||
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
|
||||
|
||||
localSocket = new sockaddr;
|
||||
memcpy(localSocket, agentLocalSocket, sizeof(sockaddr));
|
||||
|
||||
type = agentType;
|
||||
|
||||
activeSocket = NULL;
|
||||
linkedData = NULL;
|
||||
}
|
||||
|
||||
Agent::Agent(const Agent &otherAgent) {
|
||||
publicSocket = new AgentSocket(*otherAgent.publicSocket);
|
||||
localSocket = new AgentSocket(*otherAgent.localSocket);
|
||||
publicSocket = new sockaddr;
|
||||
memcpy(publicSocket, otherAgent.publicSocket, sizeof(sockaddr));
|
||||
|
||||
localSocket = new sockaddr;
|
||||
memcpy(localSocket, otherAgent.localSocket, sizeof(sockaddr));
|
||||
|
||||
if (otherAgent.activeSocket == otherAgent.publicSocket) {
|
||||
activeSocket = publicSocket;
|
||||
|
@ -36,6 +45,7 @@ Agent::Agent(const Agent &otherAgent) {
|
|||
type = otherAgent.type;
|
||||
|
||||
// copy over linkedData
|
||||
linkedData = NULL;
|
||||
}
|
||||
|
||||
Agent& Agent::operator=(Agent otherAgent) {
|
||||
|
@ -43,6 +53,10 @@ Agent& Agent::operator=(Agent otherAgent) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool Agent::operator==(const Agent& otherAgent) {
|
||||
return matches(otherAgent.publicSocket, otherAgent.localSocket, otherAgent.type);
|
||||
}
|
||||
|
||||
void Agent::swap(Agent &first, Agent &second) {
|
||||
using std::swap;
|
||||
swap(first.publicSocket, second.publicSocket);
|
||||
|
@ -58,10 +72,9 @@ Agent::~Agent() {
|
|||
delete linkedData;
|
||||
}
|
||||
|
||||
bool Agent::matches(AgentSocket *otherPublicSocket, AgentSocket *otherLocalSocket, char otherAgentType) {
|
||||
return publicSocket->port == otherPublicSocket->port
|
||||
&& localSocket->port == otherLocalSocket->port
|
||||
&& type == otherAgentType
|
||||
&& strcmp(publicSocket->address, otherPublicSocket->address) == 0
|
||||
&& strcmp(localSocket->address, otherLocalSocket->address) == 0;
|
||||
bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType) {
|
||||
// checks if two agent objects are the same agent (same type + local + public address)
|
||||
return type == otherAgentType
|
||||
&& socketMatch(publicSocket, otherPublicSocket)
|
||||
&& socketMatch(localSocket, otherLocalSocket);
|
||||
}
|
|
@ -10,19 +10,20 @@
|
|||
#define __hifi__Agent__
|
||||
|
||||
#include <iostream>
|
||||
#include "AgentSocket.h"
|
||||
#include "AgentData.h"
|
||||
#include <sys/socket.h>
|
||||
|
||||
class Agent {
|
||||
public:
|
||||
Agent();
|
||||
Agent(AgentSocket *agentPublicSocket, AgentSocket *agentLocalSocket, char agentType);
|
||||
Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType);
|
||||
Agent(const Agent &otherAgent);
|
||||
Agent& operator=(Agent otherAgent);
|
||||
bool operator==(const Agent& otherAgent);
|
||||
~Agent();
|
||||
|
||||
bool matches(AgentSocket *otherPublicSocket, AgentSocket *otherLocalSocket, char otherAgentType);
|
||||
AgentSocket *publicSocket, *localSocket, *activeSocket;
|
||||
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
||||
sockaddr *publicSocket, *localSocket, *activeSocket;
|
||||
char type;
|
||||
timeval pingStarted;
|
||||
int pingMsecs;
|
||||
|
|
|
@ -16,28 +16,58 @@ UDPSocket * AgentList::getAgentSocket() {
|
|||
return &agentSocket;
|
||||
}
|
||||
|
||||
void AgentList::processAgentData(sockaddr *senderAddress, char *packetData, size_t dataBytes) {
|
||||
switch (packetData[0]) {
|
||||
case 'D':
|
||||
{
|
||||
// list of agents from domain server
|
||||
updateList(packetData);
|
||||
break;
|
||||
}
|
||||
case 'P':
|
||||
{
|
||||
// ping from another agent
|
||||
char reply[] = "R";
|
||||
agentSocket.send(senderAddress, reply, 1);
|
||||
break;
|
||||
}
|
||||
case 'R':
|
||||
{
|
||||
// ping reply from another agent
|
||||
handlePingReply(senderAddress);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int AgentList::updateList(char *packetData) {
|
||||
int readAgents = 0;
|
||||
int scannedItems = 0;
|
||||
|
||||
char agentType;
|
||||
AgentSocket agentPublicSocket = AgentSocket();
|
||||
AgentSocket agentLocalSocket = AgentSocket();
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
Agent newAgent;
|
||||
|
||||
while((scannedItems = sscanf(packetData,
|
||||
"%c %s %hd %s %hd,",
|
||||
"%c %u %hd %u %hd,",
|
||||
&agentType,
|
||||
agentPublicSocket.address,
|
||||
&agentPublicSocket.port,
|
||||
agentLocalSocket.address,
|
||||
&agentLocalSocket.port
|
||||
&agentPublicSocket->sin_addr.s_addr,
|
||||
&agentPublicSocket->sin_port,
|
||||
&agentLocalSocket->sin_addr.s_addr,
|
||||
&agentLocalSocket->sin_port
|
||||
))) {
|
||||
|
||||
std::vector<Agent>::iterator agent;
|
||||
|
||||
for(agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
if (agent->matches(&agentPublicSocket, &agentLocalSocket, agentType)) {
|
||||
if (agent->matches((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType)) {
|
||||
// we already have this agent, stop checking
|
||||
break;
|
||||
}
|
||||
|
@ -45,7 +75,7 @@ int AgentList::updateList(char *packetData) {
|
|||
|
||||
if (agent == agents.end()) {
|
||||
// we didn't have this agent, so add them
|
||||
newAgent = Agent(&agentPublicSocket, &agentLocalSocket, agentType);
|
||||
newAgent = Agent((sockaddr *)agentPublicSocket, (sockaddr *)agentLocalSocket, agentType);
|
||||
std::cout << "Added new agent - PS: " << agentPublicSocket << " LS: " << agentLocalSocket << " AT: " << agentType << "\n";
|
||||
agents.push_back(newAgent);
|
||||
} else {
|
||||
|
@ -64,7 +94,7 @@ void AgentList::pingAgents() {
|
|||
|
||||
if (agent->activeSocket != NULL) {
|
||||
// we know which socket is good for this agent, send there
|
||||
agentSocket.send(agent->activeSocket, payload, 1);
|
||||
agentSocket.send((sockaddr *)agent->activeSocket, payload, 1);
|
||||
} else {
|
||||
// ping both of the sockets for the agent so we can figure out
|
||||
// which socket we can use
|
||||
|
@ -72,4 +102,24 @@ void AgentList::pingAgents() {
|
|||
agentSocket.send(agent->localSocket, payload, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AgentList::handlePingReply(sockaddr *agentAddress) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
// check both the public and local addresses for each agent to see if we find a match
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
sockaddr *matchedSocket = NULL;
|
||||
|
||||
if (socketMatch(agent->publicSocket, agentAddress)) {
|
||||
matchedSocket = agent->publicSocket;
|
||||
} else if (socketMatch(agent->localSocket, agentAddress)) {
|
||||
matchedSocket = agent->localSocket;
|
||||
}
|
||||
|
||||
if (matchedSocket != NULL) {
|
||||
// matched agent, stop checking
|
||||
// update the agent's ping
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,16 +21,15 @@ class AgentList {
|
|||
AgentList();
|
||||
std::vector<Agent> agents;
|
||||
int updateList(char *packetData);
|
||||
|
||||
int processAgentData(char *address, unsigned short port, char *packetData, size_t dataBytes);
|
||||
void processAgentData(sockaddr *senderAddress, char *packetData, size_t dataBytes);
|
||||
|
||||
int broadcastToAgents(char *broadcastData, size_t dataBytes, bool sendToSelf);
|
||||
void pingAgents();
|
||||
UDPSocket* getAgentSocket();
|
||||
private:
|
||||
UDPSocket agentSocket;
|
||||
int addAgent(AgentSocket *publicSocket, AgentSocket *localSocket, char agentType);
|
||||
int indexOfMatchingAgent(AgentSocket *publicSocket, AgentSocket *privateSocket, char agentType);
|
||||
|
||||
int addAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType);
|
||||
void handlePingReply(sockaddr *agentAddress);
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AgentList__) */
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// AgentSocket.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 2/19/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include "AgentSocket.h"
|
||||
|
||||
#define MAX_ADDRESS_SIZE 255
|
||||
|
||||
AgentSocket::AgentSocket() {
|
||||
address = new char[MAX_ADDRESS_SIZE];
|
||||
}
|
||||
|
||||
AgentSocket::AgentSocket(const AgentSocket &otherAgentSocket) {
|
||||
address = new char[MAX_ADDRESS_SIZE];
|
||||
strcpy(address, otherAgentSocket.address);
|
||||
port = otherAgentSocket.port;
|
||||
}
|
||||
|
||||
AgentSocket& AgentSocket::operator=(AgentSocket otherAgentSocket) {
|
||||
swap(*this, otherAgentSocket);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AgentSocket::swap(AgentSocket &first, AgentSocket &second) {
|
||||
using std::swap;
|
||||
|
||||
swap(first.address, second.address);
|
||||
swap(first.port, second.port);
|
||||
}
|
||||
|
||||
AgentSocket::~AgentSocket() {
|
||||
delete address;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// AgentSocket.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 2/19/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__AgentSocket__
|
||||
#define __hifi__AgentSocket__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class AgentSocket {
|
||||
public:
|
||||
AgentSocket();
|
||||
AgentSocket(const AgentSocket &otherAgentSocket);
|
||||
AgentSocket& operator=(AgentSocket otherAgentSocket);
|
||||
~AgentSocket();
|
||||
|
||||
char *address;
|
||||
unsigned short port;
|
||||
private:
|
||||
void swap(AgentSocket &first, AgentSocket &second);
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream & Str, AgentSocket const &socket) {
|
||||
Str << socket.address << ":" << socket.port;
|
||||
return Str;
|
||||
}
|
||||
|
||||
#endif /* defined(__hifi__AgentSocket__) */
|
|
@ -16,6 +16,26 @@
|
|||
|
||||
sockaddr_in destSockaddr, senderAddress;
|
||||
|
||||
bool socketMatch(sockaddr *first, sockaddr *second) {
|
||||
// utility function that indicates if two sockets are equivalent
|
||||
|
||||
// currently only compares two IPv4 addresses
|
||||
// expandable to IPv6 by adding else if for AF_INET6
|
||||
|
||||
if (first->sa_family != second->sa_family) {
|
||||
// not the same family, can't be equal
|
||||
return false;
|
||||
} else if (first->sa_family == AF_INET) {
|
||||
sockaddr_in *firstIn = (sockaddr_in *) first;
|
||||
sockaddr_in *secondIn = (sockaddr_in *) second;
|
||||
|
||||
return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr
|
||||
&& firstIn->sin_port == secondIn->sin_port;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UDPSocket::UDPSocket(int listeningPort) {
|
||||
// create the socket
|
||||
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
@ -48,21 +68,21 @@ UDPSocket::~UDPSocket() {
|
|||
// Receive data on this socket with retrieving address of sender
|
||||
bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) {
|
||||
|
||||
return receive(&senderAddress, receivedData, receivedBytes);
|
||||
return receive((sockaddr *)&senderAddress, receivedData, receivedBytes);
|
||||
}
|
||||
|
||||
// Receive data on this socket with the address of the sender
|
||||
bool UDPSocket::receive(sockaddr_in *recvAddress, void *receivedData, ssize_t *receivedBytes) {
|
||||
bool UDPSocket::receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes) {
|
||||
|
||||
socklen_t addressSize = sizeof(&recvAddress);
|
||||
|
||||
*receivedBytes = recvfrom(handle, receivedData, MAX_BUFFER_LENGTH_BYTES,
|
||||
0, (sockaddr *) recvAddress, &addressSize);
|
||||
0, recvAddress, &addressSize);
|
||||
|
||||
return (*receivedBytes > 0);
|
||||
}
|
||||
|
||||
int UDPSocket::send(sockaddr_in *destAddress, const void *data, size_t byteLength) {
|
||||
int UDPSocket::send(sockaddr *destAddress, const void *data, size_t byteLength) {
|
||||
// send data via UDP
|
||||
|
||||
int sent_bytes = sendto(handle, (const char*)data, byteLength,
|
||||
|
@ -82,12 +102,5 @@ int UDPSocket::send(char * destAddress, int destPort, const void *data, size_t b
|
|||
destSockaddr.sin_addr.s_addr = inet_addr(destAddress);
|
||||
destSockaddr.sin_port = htons((uint16_t)destPort);
|
||||
|
||||
return send(&destSockaddr, data, byteLength);
|
||||
}
|
||||
|
||||
int UDPSocket::send(AgentSocket *destAgentSocket, const void *data, size_t byteLength) {
|
||||
destSockaddr.sin_addr.s_addr = inet_addr(destAgentSocket->address);
|
||||
destSockaddr.sin_port = htons(destAgentSocket->port);
|
||||
|
||||
return send(&destSockaddr, data, byteLength);
|
||||
return send((sockaddr *)&destSockaddr, data, byteLength);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <iostream>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include "AgentSocket.h"
|
||||
|
||||
#define MAX_BUFFER_LENGTH_BYTES 1024
|
||||
|
||||
|
@ -20,13 +19,14 @@ class UDPSocket {
|
|||
public:
|
||||
UDPSocket(int listening_port);
|
||||
~UDPSocket();
|
||||
int send(sockaddr_in *destAddress, const void *data, size_t byteLength);
|
||||
int send(sockaddr *destAddress, const void *data, size_t byteLength);
|
||||
int send(char *destAddress, int destPort, const void *data, size_t byteLength);
|
||||
int send(AgentSocket *destAgentSocket, const void *data, size_t byteLength);
|
||||
bool receive(void *receivedData, ssize_t *receivedBytes);
|
||||
bool receive(sockaddr_in *recvAddress, void *receivedData, ssize_t *receivedBytes);
|
||||
bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes);
|
||||
private:
|
||||
int handle;
|
||||
};
|
||||
|
||||
bool socketMatch(sockaddr *first, sockaddr *second);
|
||||
|
||||
#endif /* defined(__interface__UDPSocket__) */
|
||||
|
|
Loading…
Reference in a new issue