#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#ifdef WIN32
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#endif
#ifndef WIN32
#include <unistd.h>
#endif
using namespace std;
-extern int GetRandInt(int nMax);
extern uint64_t GetRand(uint64_t nMax);
+extern void FillRand(uint8_t *buffer, size_t nCount);
/*---------------------------------------------------------------------*/
static uint64_t randfiller = GetRand(numeric_limits<uint64_t>::max());
static void stun_req_id(struct stun_header *req)
{
- const uint64_t *S_block = (const uint64_t *)StunSrvList;
- req->id.id[0] = GetRandInt(numeric_limits<int32_t>::max());
- req->id.id[1] = GetRandInt(numeric_limits<int32_t>::max());
- req->id.id[2] = GetRandInt(numeric_limits<int32_t>::max());
- req->id.id[3] = GetRandInt(numeric_limits<int32_t>::max());
+ auto S_block = (const uint64_t *)StunSrvList;
+ FillRand((uint8_t*)&req->id.id[0], sizeof(req->id.id));
req->id.id[0] |= 0x55555555;
req->id.id[1] &= 0x55555555;
unsigned char reply_buf[1024];
fd_set rfds;
struct timeval to = { STUN_TIMEOUT, 0 };
- struct sockaddr_in src;
-#ifdef WIN32
- int srclen;
-#else
- socklen_t srclen;
-#endif
int res = stun_send(sock, server, req);
if(res < 0)
res = select(sock + 1, &rfds, NULL, NULL, &to);
if (res <= 0) /* timeout or error */
return -11;
- memset(&src, 0, sizeof(src));
- srclen = sizeof(src);
- /* XXX pass -1 in the size, because stun_handle_packet might
- * write past the end of the buffer.
- */
+ struct sockaddr_in src = {};
+ socklen_t srclen = sizeof(src);
+
+ // XXX pass -1 in the size, because stun_handle_packet might
+ // write past the end of the buffer.
res = recvfrom(sock, (char *)reply_buf, sizeof(reply_buf) - 1,
0, (struct sockaddr *)&src, &srclen);
if (res <= 0)
return -12;
- memset(mapped, 0, sizeof(struct sockaddr_in));
return stun_handle_packet(sock, &src, reply_buf, res, stun_get_mapped, mapped);
} // StunRequest2
-/*---------------------------------------------------------------------*/
static int StunRequest(const char *host, uint16_t port, struct sockaddr_in *mapped) {
struct hostent *hostinfo = gethostbyname(host);
- if(hostinfo == NULL)
+ if (hostinfo == NULL)
return -1;
- SOCKET sock = INVALID_SOCKET;
- struct sockaddr_in server, client;
- memset(&server, 0, sizeof(server));
- memset(&client, 0, sizeof(client));
- server.sin_family = client.sin_family = AF_INET;
+ SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock == INVALID_SOCKET)
+ return -2;
+ struct sockaddr_in server = {}, client = {};
+
+ server.sin_family = client.sin_family = AF_INET;
server.sin_addr = *(struct in_addr*) hostinfo->h_addr;
server.sin_port = htons(port);
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if(sock == INVALID_SOCKET)
- return -2;
-
client.sin_addr.s_addr = htonl(INADDR_ANY);
int rc = -3;
- if(bind(sock, (struct sockaddr*)&client, sizeof(client)) >= 0)
+ if (::bind(sock, (struct sockaddr*)&client, sizeof(client)) != SOCKET_ERROR)
rc = StunRequest2(sock, &server, mapped);
CloseSocket(sock);
return rc;
} // StunRequest
-/*---------------------------------------------------------------------*/
// Input: two random values (pos, step) for generate uniuqe way over server
// list
// Output: populate struct struct mapped
// Retval:
-
int GetExternalIPbySTUN(uint64_t rnd, struct sockaddr_in *mapped, const char **srv) {
randfiller = rnd;
uint16_t pos = rnd;