diff --git a/dev/SocketsBase/SocketsBase.cbp b/dev/SocketsBase/SocketsBase.cbp new file mode 100644 index 000000000..09c432605 --- /dev/null +++ b/dev/SocketsBase/SocketsBase.cbp @@ -0,0 +1,70 @@ + + + + + + diff --git a/dev/SocketsBase/bin/Debug/SocketsBase b/dev/SocketsBase/bin/Debug/SocketsBase index c61948bab..f602705e3 100755 Binary files a/dev/SocketsBase/bin/Debug/SocketsBase and b/dev/SocketsBase/bin/Debug/SocketsBase differ diff --git a/dev/SocketsBase/http_functions.cpp b/dev/SocketsBase/http_functions.cpp index b8246c59b..1827713d6 100644 --- a/dev/SocketsBase/http_functions.cpp +++ b/dev/SocketsBase/http_functions.cpp @@ -4,12 +4,46 @@ #include #include #include +#include +#include +#include +#include namespace HTTP { CURL *curl; CURLcode res; +struct string { + char *ptr; + size_t len; +}; + +void init_string(struct string *s) { + s->len = 0; + s->ptr = (char*)(malloc(s->len+1)); + if (s->ptr == NULL) { + fprintf(stderr, "malloc() failed\n"); + exit(EXIT_FAILURE); + } + s->ptr[0] = '\0'; +} + +size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) +{ + size_t new_len = s->len + size*nmemb; + s->ptr = (char*)(realloc(s->ptr, new_len+1)); + if (s->ptr == NULL) { + fprintf(stderr, "realloc() failed\n"); + exit(EXIT_FAILURE); + } + memcpy(s->ptr+s->len, ptr, size*nmemb); + s->ptr[new_len] = '\0'; + s->len = new_len; + + return size*nmemb; +} + static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { ((std::string*)userp)->append((char*)contents, size * nmemb); @@ -26,16 +60,16 @@ void init() std::string getPage(std::string url) { - std::string readBuffer = ""; + struct string readBuffer; + init_string(&readBuffer); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); res = curl_easy_perform(curl); if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); - readBuffer.erase(readBuffer.begin()+64, readBuffer.end()); - return readBuffer; + return readBuffer.ptr; } void shutdown() diff --git a/dev/SocketsBase/main.cpp b/dev/SocketsBase/main.cpp index 4e5c8733c..0d4061e08 100644 --- a/dev/SocketsBase/main.cpp +++ b/dev/SocketsBase/main.cpp @@ -5,6 +5,9 @@ #include "server_network_manager.hpp" #include "protocol_manager.hpp" #include "protocols/get_public_address.hpp" +#include "http_functions.hpp" +#include "protocols/connect_to_server.hpp" + #include #include @@ -22,23 +25,40 @@ void* foo(void* data) int main() { + HTTP::init(); + std::string answer; cout << "host or client:"; answer = "client"; cin >> answer; if (answer == "client") { + /// NICKNAME : + std::string nickname; + cout << "Nickname="; + std::cin >> nickname; + /// PASSWORD : + std::string password; + cout << "Password="; + std::cin >> password; + ConnectToServer* connectionProtocol = new ConnectToServer(NULL); + connectionProtocol->setPassword(password); + connectionProtocol->setUsername(nickname); + + ClientNetworkManager clt; clt.run(); protocolListener = new ProtocolManager(); - pthread_t* thrd = (pthread_t*)(malloc(sizeof(pthread_t))); pthread_create(thrd, NULL, foo, NULL); // start a retreive stun addr protocol - Protocol* prt = new GetPublicAddress(NULL); + Protocol* prt = new GetPublicAddress(connectionProtocol); + prt->setListener(protocolListener); + connectionProtocol->setListener(protocolListener); + protocolListener->runProtocol(prt); clt.connect(0x0100007f, 7000); // addr in little endian, real address is 7f 00 00 01 (127.0.0.1) diff --git a/dev/SocketsBase/network_manager.cpp b/dev/SocketsBase/network_manager.cpp index e26fb0c35..7feb176fc 100644 --- a/dev/SocketsBase/network_manager.cpp +++ b/dev/SocketsBase/network_manager.cpp @@ -31,14 +31,6 @@ void NetworkManager::setManualSocketsMode(bool manual) instance->getHost()->startListening(); } -void NetworkManager::sendRawPacket(uint8_t* data, int length, unsigned int dstIp, unsigned short dstPort) -{ - instance->getHost()->sendRawPacket(data, length, dstIp, dstPort); -} -uint8_t* NetworkManager::receiveRawPacket() -{ - return instance->getHost()->receiveRawPacket(0,0); -} void NetworkManager::receptionCallback(char* data) { instance->packetReceived(data); @@ -46,5 +38,5 @@ void NetworkManager::receptionCallback(char* data) STKHost* NetworkManager::getHost() { - return m_localhost; + return instance->m_localhost; } diff --git a/dev/SocketsBase/network_manager.hpp b/dev/SocketsBase/network_manager.hpp index 884c02ec7..b1e2023c7 100644 --- a/dev/SocketsBase/network_manager.hpp +++ b/dev/SocketsBase/network_manager.hpp @@ -17,12 +17,11 @@ class NetworkManager static void setManualSocketsMode(bool manual); static void sendRawPacket(uint8_t* data, int length, unsigned int dstIp, unsigned short dstPort); - static uint8_t* receiveRawPacket(); static void receptionCallback(char* data); virtual void packetReceived(char* data) = 0; - STKHost* getHost(); + static STKHost* getHost(); protected: std::vector m_peers; STKHost* m_localhost; diff --git a/dev/SocketsBase/protocols/connect_to_server.cpp b/dev/SocketsBase/protocols/connect_to_server.cpp new file mode 100644 index 000000000..37cfa65a6 --- /dev/null +++ b/dev/SocketsBase/protocols/connect_to_server.cpp @@ -0,0 +1,80 @@ +#include "connect_to_server.hpp" + +#include "../http_functions.hpp" + +#include + +ConnectToServer::ConnectToServer(CallbackObject* callbackObject) : Protocol(callbackObject) +{ + m_ownPublicIp = 0; + m_ownPublicPort = 0; +} + +ConnectToServer::~ConnectToServer() +{ +} + +void ConnectToServer::setup() +{ +} + +void ConnectToServer::messageReceived(uint8_t* data) +{ + +} + +void ConnectToServer::start() +{ + if (m_ownPublicIp == 0 || m_ownPublicPort == 0 || m_username == "" || m_password == "") + { + printf("You have to set the public ip:port and username:password before starting this protocol.\n"); + m_listener->protocolTerminated(this); + } +} + +void ConnectToServer::update() +{ + if (m_state == NOTHING) + { + char url[512]; + sprintf(url, "http://stkconnect.freeserver.me/log.php?set&nick=%s&ip=%u&port=%u&pwd=%s", m_username.c_str(), m_ownPublicIp, m_ownPublicPort, m_password.c_str()); + std::string result = HTTP::getPage(url); + //printf("Result from web page is %s\n", result.c_str()); + if (result[0] == 's' && result[1] == 'u' && result[2] == 'c') + { + printf("Address set.\n"); + m_state = ADDRESS_KNOWN_ONLINE; + } + if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i') + { + printf("Login fail.\n"); + m_state = ADDRESS_KNOWN_ONLINE; + } + } + else if (m_state == ADDRESS_KNOWN_ONLINE) + { + } + else if (m_state == PEER_ADDRESS_RETREIVED) + { + } + else if (m_state == CONNECTED) + { + } + +} + +void ConnectToServer::setSelfAddress(uint32_t ip, uint16_t port) +{ + m_ownPublicIp = ip; + m_ownPublicPort = port; +} + +void ConnectToServer::setUsername(std::string username) +{ + m_username = username; +} + +void ConnectToServer::setPassword(std::string password) +{ + m_password = password; +} diff --git a/dev/SocketsBase/protocols/connect_to_server.hpp b/dev/SocketsBase/protocols/connect_to_server.hpp new file mode 100644 index 000000000..02f78b9c8 --- /dev/null +++ b/dev/SocketsBase/protocols/connect_to_server.hpp @@ -0,0 +1,37 @@ +#ifndef CONNECT_TO_SERVER_HPP +#define CONNECT_TO_SERVER_HPP + +#include "../protocol.hpp" +#include + +class ConnectToServer : public Protocol, public CallbackObject +{ + public: + ConnectToServer(CallbackObject* callbackObject); + virtual ~ConnectToServer(); + + virtual void messageReceived(uint8_t* data); + virtual void setup(); + virtual void start(); + virtual void update(); + + void setSelfAddress(uint32_t ip, uint16_t port); + void setUsername(std::string username); + void setPassword(std::string password); + + protected: + uint32_t m_ownPublicIp; + uint16_t m_ownPublicPort; + std::string m_username; + std::string m_password; + enum STATE + { + NOTHING, + ADDRESS_KNOWN_ONLINE, + PEER_ADDRESS_RETREIVED, + CONNECTED + }; + STATE m_state; +}; + +#endif // CONNECT_TO_SERVER_HPP diff --git a/dev/SocketsBase/protocols/get_public_address.cpp b/dev/SocketsBase/protocols/get_public_address.cpp index 593a1220a..c5fe8a587 100644 --- a/dev/SocketsBase/protocols/get_public_address.cpp +++ b/dev/SocketsBase/protocols/get_public_address.cpp @@ -1,6 +1,7 @@ #include "get_public_address.hpp" #include "../network_manager.hpp" +#include "connect_to_server.hpp" #include #include @@ -85,12 +86,13 @@ void GetPublicAddress::update() printf("Querrying STUN server 132.177.123.6\n"); unsigned int dst = 132*256*256*256+177*256*256+123*256+6; NetworkManager::setManualSocketsMode(true); - NetworkManager::sendRawPacket(bytes, 20, dst, 3478); + NetworkManager::getHost()->sendRawPacket(bytes, 20, dst, 3478); m_state = TEST_SENT; } if (m_state == TEST_SENT) { - uint8_t* data = NetworkManager::receiveRawPacket(); + unsigned int dst = 132*256*256*256+177*256*256+123*256+6; + uint8_t* data = NetworkManager::getHost()->receiveRawPacket(dst, 3478); assert(data); // check that the stun response is a response, contains the magic cookie and the transaction ID @@ -169,6 +171,9 @@ void GetPublicAddress::update() printf("The public address has been found : %i.%i.%i.%i:%i\n", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port); m_state = ADDRESS_KNOWN; NetworkManager::setManualSocketsMode(false); + ConnectToServer* cbObj = static_cast(m_callbackObject); + cbObj->setSelfAddress(address, port); + m_listener->runProtocol(cbObj); } else m_state = NOTHING_DONE; // need to re-send the stun request diff --git a/dev/SocketsBase/stk_host.cpp b/dev/SocketsBase/stk_host.cpp index fd8892045..d601df55b 100644 --- a/dev/SocketsBase/stk_host.cpp +++ b/dev/SocketsBase/stk_host.cpp @@ -120,11 +120,11 @@ uint8_t* STKHost::receiveRawPacket(unsigned int dstIp, unsigned short dstPort) int len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &fromlen); int i = 0; - while(len < 0 - && (uint8_t)(addr.sa_data[2]) != (dstIp>>24&0xff) + while(len < 0 || ( + (uint8_t)(addr.sa_data[2]) != (dstIp>>24&0xff) && (uint8_t)(addr.sa_data[3]) != (dstIp>>16&0xff) && (uint8_t)(addr.sa_data[4]) != (dstIp>>8&0xff) - && (uint8_t)(addr.sa_data[5]) != (dstIp&0xff)) // wait to receive the message because enet sockets are non-blocking + && (uint8_t)(addr.sa_data[5]) != (dstIp&0xff))) // wait to receive the message because enet sockets are non-blocking { i++; len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &fromlen);