{
// MH in case anbody has a better position :-)
pthread_mutex_init(&threadClientMutex, NULL);
+ tcpServerPort = 0;
}
MVPServer::~MVPServer()
dsyslog("VOMP: Logging disabled");
}
+ // Get UDP port number for discovery service
+
+ int fail = 1;
+ int udpport = config.getValueLong("General", "UDP port", &fail);
+ if (fail) udpport = 51051;
+
// Work out a name for this server
char* serverName;
if (!serverName) // If not, get the hostname
{
serverName = new char[1024];
- if (gethostname(serverName, 1024)) // if not, just use "-"
+ if (gethostname(serverName, 1024)) // if not, set default
{
- strcpy(serverName, "-");
+ strcpy(serverName, "VOMP Server");
}
}
- int udpSuccess = udpr.run(serverName);
+ // Get VOMP server TCP port to give to UDP replier to put in packets
+ fail = 1;
+ tcpServerPort = config.getValueLong("General", "TCP port", &fail);
+ if (fail) tcpServerPort = 3024;
+
+ int udpSuccess = udpr.run(udpport, serverName, tcpServerPort);
delete[] serverName;
struct sockaddr_in address;
address.sin_family = AF_INET;
- address.sin_port = htons(3024);
+ address.sin_port = htons(tcpServerPort);
address.sin_addr.s_addr = INADDR_ANY;
socklen_t length = sizeof(address);
MVPRelay mvprelay;
int listeningSocket;
char* configDir;
+ USHORT tcpServerPort;
};
#endif
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "vompclientrrproc.h"
+
#include "udpreplier.h"
UDPReplier::UDPReplier()
{
- serverName = NULL;
+ message = NULL;
+ messageLen = 0;
}
UDPReplier::~UDPReplier()
{
if (threadIsActive()) threadCancel();
- if (serverName) delete[] serverName;
- serverName = NULL;
+ if (message) delete[] message;
+ message = NULL;
return 1;
}
-int UDPReplier::run(char* tserverName)
+int UDPReplier::run(USHORT port, char* serverName, USHORT serverPort)
{
if (threadIsActive()) return 1;
- serverName = new char[strlen(tserverName)+1];
- strcpy(serverName, tserverName);
-
- if (!ds.init(3024))
+ /*
+ VOMP Discovery Protocol V1
+
+ Client transmits: "VDP-0001\0<6-byte MAC>" on ports 51051-51055
+
+ Server responds:
+
+ Field 1 p0: 9 bytes "VDP-0002\0"
+
+ Field 2 p9, 1 byte:
+
+ 0 = no IP specified
+ 4 = first 4 bytes of field 2 are IPv4 address of server
+ 6 = field 2 16 bytes are IPv6 address of server
+
+ Field 3, p10, 16 bytes:
+ As described above. If field 1 is 0, this should be all zeros. If this is an IPv4 address, remaining bytes should be zeros.
+
+ Field 4 p26, 2 bytes:
+ Port number of server
+
+ Field 5 p28, 4 bytes:
+ VOMP protocol version (defined in vdr.cc)
+
+ Field 6 p32, variable length
+ String of server name, null terminated
+ */
+
+ messageLen = strlen(serverName) + 33;
+ message = new char[messageLen];
+ memset(message, 0, messageLen);
+ // by zeroing the packet, this sets no ip address return information
+
+ strcpy(message, "VDP-0002");
+
+ USHORT temp = htons(serverPort);
+ memcpy(&message[26], &temp, 2);
+
+ ULONG temp2 = htonl(VompClientRRProc::getProtocolVersion());
+ memcpy(&message[28], &temp2, 4);
+
+ strcpy(&message[32], serverName);
+
+ if (!ds.init(port))
{
shutdown();
return 0;
retval = ds.waitforMessage(0);
if (retval == 1) continue;
- if (!strcmp(ds.getData(), "VOMP"))
+ if (!strncmp(ds.getData(), "VDP-0001", 8))
{
Log::getInstance()->log("UDPReplier", Log::DEBUG, "UDP request from %s", ds.getFromIPA());
- ds.send(ds.getFromIPA(), 3024, serverName, strlen(serverName));
+ ds.send(ds.getFromIPA(), ds.getFromPort(), message, messageLen);
}
}
}
UDPReplier();
virtual ~UDPReplier();
- int run(char* tserverName);
+ int run(USHORT udpPort, char* serverName, USHORT serverPort);
int shutdown();
private:
void threadMethod();
DatagramSocket ds;
- char* serverName;
+ char* message;
+ int messageLen;
};
#endif
bool ResumeIDLock;
-#define VOMP_PROTOCOLL_VERSION 0x00000100
+ULONG VompClientRRProc::VOMP_PROTOCOL_VERSION = 0x00000100;
// format is aabbccdd
-// cc is release protocol version, increase with every release, that changes protocoll
+// cc is release protocol version, increase with every release, that changes protocol
// dd is development protocol version, set to zero at every release,
-// increase for every protocoll change in git
-// bb not equal zero should indicate a non loggytronic protocoll
+// increase for every protocol change in git
+// bb not equal zero should indicate a non loggytronic protocol
// aa is reserved for future use
+ULONG VompClientRRProc::getProtocolVersion()
+{
+ return VOMP_PROTOCOL_VERSION;
+}
+
VompClientRRProc::VompClientRRProc(VompClient& x)
: x(x)
{
resp->addULONG(timeNow);
resp->addLONG(timeOffset);
- resp->addULONG(VOMP_PROTOCOLL_VERSION);
+ resp->addULONG(VOMP_PROTOCOL_VERSION);
resp->finalise();
x.tcp.sendPacket(resp->getPtr(), resp->getLen());
log->log("RRProc", Log::DEBUG, "written login reply len %lu", resp->getLen());
public:
VompClientRRProc(VompClient& x);
~VompClientRRProc();
+ static ULONG getProtocolVersion();
bool init();
bool recvRequest(RequestPacket*);
RequestPacket* req;
RequestPacketQueue req_queue;
ResponsePacket* resp;
+ static ULONG VOMP_PROTOCOL_VERSION;
Log* log;
};