Fixed errors and removed unused code in the C client.

- Fixed a buffer overflow in sendCTRL.
 - Fixed incorrect inderection in readUDP.
 - Removed unused usleep function.
 - Removed redundant include of WS2tcpip.h
 - Fixed widespread error where sendUDP's return value was not being checked correctly.
 - Updated signature of openUDP to place optional parameters at the end
 - Fixed bug in CTRL command where the buffer length was not correctly set.
 - Fixed setCONN to correctlly reset the client's socket.
This commit is contained in:
Jason Watkins
2015-04-16 16:23:25 -07:00
parent 556b3622ee
commit 55f3953955
3 changed files with 77 additions and 79 deletions

View File

@@ -48,28 +48,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#ifdef _WIN32 /* WIN32 SYSTEM */
#include <WS2tcpip.h>
// From http://www.c-plusplus.de/forum/109539-full
void usleep(__int64 usec)
{
HANDLE timer;
LARGE_INTEGER ft;
ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
timer = CreateWaitableTimer(NULL, TRUE, NULL); void printError(char *functionName, char *format, ...)
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}
#endif
void printError(char *functionName, char *format, ...);
short sendRequest(XPCSocket recfd, char DREFArray[][100], short DREFSizes[], short listLength);
void printError(char *functionName, char *format)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@@ -84,7 +66,12 @@ void printError(char *functionName, char *format)
/*****************************************************************************/ /*****************************************************************************/
/**** Low Level UDP functions ****/ /**** Low Level UDP functions ****/
/*****************************************************************************/ /*****************************************************************************/
XPCSocket openUDP(unsigned short port, const char *xpIP, unsigned short xpPort) XPCSocket aopenUDP(const char *xpIP, unsigned short xpPort)
{
openUDP(xpIP, xpPort, 0);
}
XPCSocket openUDP(const char *xpIP, unsigned short xpPort, unsigned short port)
{ {
XPCSocket sock; XPCSocket sock;
@@ -136,12 +123,12 @@ XPCSocket openUDP(unsigned short port, const char *xpIP, unsigned short xpPort)
return sock; return sock;
} }
void closeUDP(XPCSocket socketNumber) void closeUDP(XPCSocket sock)
{ {
#ifdef _WIN32 #ifdef _WIN32
int result = closesocket(socketNumber.sock); int result = closesocket(sock.sock);
#else #else
int result = close(socketNumber.sock); int result = close(sock.sock);
#endif #endif
if (result < 0) if (result < 0)
{ {
@@ -178,9 +165,8 @@ int sendUDP(XPCSocket sock, char buffer[], int len)
return result; return result;
} }
int readUDP(XPCSocket sock, char buffer[], int len, struct sockaddr* recvaddr) int readUDP(XPCSocket sock, char buffer[], int len)
{ {
socklen_t recvaddrlen = sizeof(*recvaddr);
#ifdef _WIN32 #ifdef _WIN32
// Windows readUDP needs the select command- minimum timeout is 1ms. // Windows readUDP needs the select command- minimum timeout is 1ms.
// Without this playback becomes choppy // Without this playback becomes choppy
@@ -211,10 +197,10 @@ int readUDP(XPCSocket sock, char buffer[], int len, struct sockaddr* recvaddr)
// No data // No data
return 0; return 0;
} }
status = recvfrom(sock.sock, buffer, len, 0, (struct sockaddr*)&recvaddr, &recvaddrlen); status = recv(sock.sock, buffer, len, 0);
#else #else
// For apple or linux-just read - will timeout in 0.5 ms // For apple or linux-just read - will timeout in 0.5 ms
status = (int)recvfrom(sock.sock, dataRef, len, 0, recvaddr, &recvaddrlen); status = (int)recv(sock.sock, dataRef, len, 0);
#endif #endif
if (status < 0) if (status < 0)
{ {
@@ -229,19 +215,34 @@ int readUDP(XPCSocket sock, char buffer[], int len, struct sockaddr* recvaddr)
/*****************************************************************************/ /*****************************************************************************/
/**** Configuration functions ****/ /**** Configuration functions ****/
/*****************************************************************************/ /*****************************************************************************/
int setCONN(XPCSocket sock) int setCONN(XPCSocket* sock, unsigned short port)
{ {
// Set up command // Set up command
char buffer[32] = "CONN"; char buffer[32] = "CONN";
memcpy(&buffer[5], &sock.port, 2); memcpy(&buffer[5], &port, 2);
// Send command // Send command
if (sendUDP(sock, buffer, 7) != 0) if (sendUDP(*sock, buffer, 7) < 0)
{ {
printError("setCONN", "Failed to send command"); printError("setCONN", "Failed to send command");
return -1; return -1;
} }
// Switch socket
closeUDP(*sock);
*sock = openUDP(sock->xpIP, sock->xpPort, port);
// Read response // Read response
if (readUDP(sock, buffer, 32, NULL) <= 0) int result;
for (int i = 0; i < 64; ++i)
{
result = readUDP(*sock, buffer, 32);
if (result != 0)
{
break;
}
}
if (result <= 0)
{ {
printError("setCONN", "Failed to read response"); printError("setCONN", "Failed to read response");
return -2; return -2;
@@ -261,7 +262,7 @@ int pauseSim(XPCSocket sock, char pause)
char buffer[6] = "SIMU"; char buffer[6] = "SIMU";
buffer[5] = pause == 0 ? 0 : 1; buffer[5] = pause == 0 ? 0 : 1;
// Send command // Send command
if (sendUDP(sock, buffer, 6) != 0) if (sendUDP(sock, buffer, 6) < 0)
{ {
printError("pauseSim", "Failed to send command"); printError("pauseSim", "Failed to send command");
return -1; return -1;
@@ -297,7 +298,7 @@ int sendDATA(XPCSocket sock, float dataRef[][9], int rows)
memcpy(&buffer[9 + i*step], &dataRef[i][1], 8 * sizeof(float)); memcpy(&buffer[9 + i*step], &dataRef[i][1], 8 * sizeof(float));
} }
// Send command // Send command
if (sendUDP(sock, buffer, len ) != 0) if (sendUDP(sock, buffer, len ) < 0)
{ {
printError("sendDATA", "Failed to send command"); printError("sendDATA", "Failed to send command");
return -2; return -2;
@@ -319,7 +320,7 @@ int readDATA(XPCSocket sock, float dataRef[][9], int rows)
// Read data // Read data
char buffer[4829] = { 0 }; char buffer[4829] = { 0 };
int result = readUDP(sock, buffer, 5120, NULL); int result = readUDP(sock, buffer, 5120);
if (result <= 0) if (result <= 0)
{ {
printError("readDATA", "Failed to read from socket."); printError("readDATA", "Failed to read from socket.");
@@ -376,7 +377,7 @@ int setDREF(XPCSocket sock, const char* dref, float values[], int size)
memcpy(buffer + 7 + drefLen, values, size * sizeof(float)); memcpy(buffer + 7 + drefLen, values, size * sizeof(float));
// Send command // Send command
if (sendUDP(sock, buffer, len) != 0) if (sendUDP(sock, buffer, len) < 0)
{ {
printError("setDREF", "Failed to send command"); printError("setDREF", "Failed to send command");
return -2; return -2;
@@ -405,7 +406,7 @@ int sendDREFRequest(XPCSocket sock, const char* drefs[], unsigned char count)
len += drefLen; len += drefLen;
} }
// Send Command // Send Command
if (sendUDP(sock, buffer, len) != 0) if (sendUDP(sock, buffer, len) < 0)
{ {
printError("getDREFs", "Failed to send command"); printError("getDREFs", "Failed to send command");
return -2; return -2;
@@ -419,16 +420,20 @@ int getDREFResponse(XPCSocket sock, float* values[], unsigned char count, int si
// Read data. Try 40 times to read, then give up. // Read data. Try 40 times to read, then give up.
// TODO: Why not just set the timeout to 40ms? // TODO: Why not just set the timeout to 40ms?
int result; int result;
for (int i = 0; i < 40; ++i) for (int i = 0; i < 512; ++i)
{ {
result = readUDP(sock, buffer, 65536, NULL); result = readUDP(sock, buffer, 65536);
if (result > 0) if (result > 0)
{ {
break; break;
} }
if (result < 0) if (result < 0)
{ {
#ifdef _WIN32
printError("getDREFs", "Read operation failed. (%d)", WSAGetLastError());
#else
printError("getDREFs", "Read operation failed."); printError("getDREFs", "Read operation failed.");
#endif
return -1; return -1;
} }
} }
@@ -531,7 +536,7 @@ int sendPOSI(XPCSocket sock, float values[], int size, char ac)
} }
// Send Command // Send Command
if (sendUDP(sock, buffer, 40) != 0) if (sendUDP(sock, buffer, 40) < 0)
{ {
printError("sendPOSI", "Failed to send command"); printError("sendPOSI", "Failed to send command");
return -2; return -2;
@@ -586,16 +591,15 @@ int sendCTRL(XPCSocket sock, float values[], int size, char ac)
cur += sizeof(float); cur += sizeof(float);
} }
} }
buffer[27] = ac; buffer[26] = ac;
// Send Command // Send Command
if (sendUDP(sock, buffer, 40) != 0) if (sendUDP(sock, buffer, 27) < 0)
{ {
printError("sendCTRL", "Failed to send command"); printError("sendCTRL", "Failed to send command");
return -2; return -2;
} }
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/**** End CTRL functions ****/ /**** End CTRL functions ****/
@@ -630,7 +634,7 @@ int sendTEXT(XPCSocket sock, char* msg, int x, int y)
strncpy(buffer + 14, msg, msgLen); strncpy(buffer + 14, msg, msgLen);
// Send Command // Send Command
if (sendUDP(sock, buffer, 40) != 0) if (sendUDP(sock, buffer, 40) < 0)
{ {
printError("sendTEXT", "Failed to send command"); printError("sendTEXT", "Failed to send command");
return -2; return -2;
@@ -661,7 +665,7 @@ int sendWYPT(XPCSocket sock, WYPT_OP op, float points[], int count)
memcpy(buffer + 7, points, ptLen); memcpy(buffer + 7, points, ptLen);
// Send Command // Send Command
if (sendUDP(sock, buffer, 40) != 0) if (sendUDP(sock, buffer, 40) < 0)
{ {
printError("sendWYPT", "Failed to send command"); printError("sendWYPT", "Failed to send command");
return -2; return -2;

View File

@@ -49,11 +49,11 @@ typedef struct
char xpIP[16]; char xpIP[16];
unsigned short xpPort; unsigned short xpPort;
#ifdef _WIN32 #ifdef _WIN32
SOCKET sock; SOCKET sock;
#else #else
int sock; int sock;
#endif #endif
} XPCSocket; } XPCSocket;
typedef enum typedef enum
@@ -64,13 +64,14 @@ typedef enum
} WYPT_OP; } WYPT_OP;
// Low Level UDP Functions // Low Level UDP Functions
XPCSocket openUDP(unsigned short port, const char *xpIP, unsigned short xpPort); XPCSocket aopenUDP(const char *xpIP, unsigned short xpPort);
XPCSocket openUDP(const char *xpIP, unsigned short xpPort, unsigned short port);
void closeUDP(XPCSocket sock); void closeUDP(XPCSocket sock);
int sendUDP(XPCSocket sock, char buffer[], int len); int sendUDP(XPCSocket sock, char buffer[], int len);
int readUDP(XPCSocket sock, char buffer[], int len, struct sockaddr* recvaddr); int readUDP(XPCSocket sock, char buffer[], int len);
// Configuration // Configuration
int setCONN(XPCSocket sock); int setCONN(XPCSocket* sock, unsigned short port);
int pauseSim(XPCSocket sock, char pause); int pauseSim(XPCSocket sock, char pause);
// X-Plane UDP DATA // X-Plane UDP DATA

View File

@@ -34,16 +34,16 @@ void runTest(int (*test)(), char* name)
int openTest() // openUDP Test int openTest() // openUDP Test
{ {
XPCSocket sock = openUDP( 49062, "127.0.0.1", 49009 ); XPCSocket sock = openUDP("127.0.0.1", 49009, 49062);
closeUDP(sock); closeUDP(sock);
return 0; return 0;
} }
int closeTest() // closeUDP test int closeTest() // closeUDP test
{ {
XPCSocket sendPort = openUDP( 49063, "127.0.0.1", 49009 ); XPCSocket sendPort = openUDP("127.0.0.1", 49009, 49063);
closeUDP(sendPort); closeUDP(sendPort);
sendPort = openUDP(49063, "127.0.0.1", 49009); sendPort = openUDP("127.0.0.1", 49009, 49063);
closeUDP(sendPort); closeUDP(sendPort);
return 0; return 0;
} }
@@ -53,8 +53,8 @@ int sendReadTest() // send/read Test
// Initialization // Initialization
char test[] = {0, 1, 2, 3, 5}; char test[] = {0, 1, 2, 3, 5};
char buf[5] = {0}; char buf[5] = {0};
XPCSocket outSock = openUDP(49064, "127.0.0.1", 49063); XPCSocket outSock = openUDP("127.0.0.1", 49063, 49064);
XPCSocket inSock = openUDP(49063, "127.0.0.1", 49009); XPCSocket inSock = openUDP("127.0.0.1", 49009, 49063);
// Execution // Execution
sendUDP(outSock, test, sizeof(test)); sendUDP(outSock, test, sizeof(test));
@@ -79,7 +79,7 @@ int sendReadTest() // send/read Test
int sendTEXTTest() int sendTEXTTest()
{ {
// Setup // Setup
XPCSocket sendPort = openUDP(49064, "127.0.0.1", 49009); XPCSocket sendPort = openUDP("127.0.0.1", 49009, 49064);
int x = 100; int x = 100;
int y = 700; int y = 700;
char* msg = "XPlaneConnect test message. Now with 100% fewer new lines!"; char* msg = "XPlaneConnect test message. Now with 100% fewer new lines!";
@@ -103,7 +103,7 @@ int requestDREFTest() // Request DREF Test (Required for next tests)
}; };
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
XPCSocket sock = openUDP(49064, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49064);
// Setup // Setup
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@@ -139,7 +139,7 @@ int sendDREFTest() // sendDREF test
}; };
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
XPCSocket sock = openUDP(49066, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49066);
float value = 1.0F; float value = 1.0F;
// Setup // Setup
@@ -183,7 +183,7 @@ int sendDATATest() // sendDATA test
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
float DATA[4][9]; float DATA[4][9];
XPCSocket sock = openUDP(49066, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49066);
// Setup // Setup
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
@@ -240,7 +240,7 @@ int psendCTRLTest() // sendCTRL test
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
float CTRL[6] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F }; float CTRL[6] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F };
XPCSocket sock = openUDP(49066, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49066);
// Setup // Setup
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
@@ -287,7 +287,7 @@ int sendCTRLTest()
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
float CTRL[6] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F }; float CTRL[6] = { 0.0F, 0.0F, 0.0F, 0.8F, 1.0F, 0.5F };
XPCSocket sock = openUDP(49066, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49066);
// Setup // Setup
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
@@ -336,7 +336,7 @@ int sendPOSITest() // sendPOSI test
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
float POSI[8] = { 37.524F, -122.06899F, 2500, 0, 0, 0, 1 }; float POSI[8] = { 37.524F, -122.06899F, 2500, 0, 0, 0, 1 };
XPCSocket sock = openUDP(49063, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49063);
// Setup // Setup
for (i = 0; i < 100; i++) for (i = 0; i < 100; i++)
@@ -376,7 +376,7 @@ int sendPOSITest() // sendPOSI test
int sendWYPTTest() int sendWYPTTest()
{ {
// Setup // Setup
XPCSocket sock = openUDP(49064, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49064);
float points[] = float points[] =
{ {
37.5245F, -122.06899F, 2500, 37.5245F, -122.06899F, 2500,
@@ -415,7 +415,7 @@ int pauseTest() // pauseSim test
}; };
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
XPCSocket sock = openUDP(49064, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49064);
// Setup // Setup
for (i = 0; i < 100; i++) for (i = 0; i < 100; i++)
@@ -442,7 +442,7 @@ int pauseTest() // pauseSim test
} }
// Reopen // Reopen
sock = openUDP(49064, "127.0.0.1", 49009); sock = openUDP("127.0.0.1", 49009, 49064);
// Execute 2 // Execute 2
pauseSim(sock, 0); pauseSim(sock, 0);
@@ -473,7 +473,7 @@ int connTest() // setConn test
}; };
float* data[100]; float* data[100];
int sizes[100]; int sizes[100];
XPCSocket sock = openUDP(49067, "127.0.0.1", 49009); XPCSocket sock = openUDP("127.0.0.1", 49009, 49067);
#if (__APPLE__ || __linux) #if (__APPLE__ || __linux)
usleep(0); usleep(0);
#endif #endif
@@ -482,12 +482,11 @@ int connTest() // setConn test
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
data[i] = (float*)malloc(40 * sizeof(float)); data[i] = (float*)malloc(40 * sizeof(float));
sizes[i] -= 40; sizes[i] = 40;
} }
// Execution // Execution
sock.port = 49055; setCONN(&sock, 49055);
setCONN(sock);
int result = getDREF(sock, drefs[0], data[0], sizes); int result = getDREF(sock, drefs[0], data[0], sizes);
// Close // Close
@@ -498,12 +497,6 @@ int connTest() // setConn test
{ {
return -1; return -1;
} }
// Set up for next test
sock = openUDP( 49055, "127.0.0.1", 49009 );
sock.port = 49008;
setCONN(sock);
closeUDP(sock);
return 0; return 0;
} }