basic protocol intrication, sending address info online, a client can set his public transport adress (ip:port) in a sql database

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@12873 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-06-18 00:42:11 +00:00
parent 9e990e76e0
commit 57b7534a6d
10 changed files with 259 additions and 22 deletions

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="SocketsBase" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/SocketsBase" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/SocketsBase" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
</Compiler>
<Linker>
<Add option="-lpthread" />
<Add option="-lcurl" />
<Add library="../../lib/enet/build/libenet.a" />
</Linker>
<Unit filename="callback_object.cpp" />
<Unit filename="callback_object.hpp" />
<Unit filename="client_network_manager.cpp" />
<Unit filename="client_network_manager.hpp" />
<Unit filename="http_functions.cpp" />
<Unit filename="http_functions.hpp" />
<Unit filename="main.cpp" />
<Unit filename="network_manager.cpp" />
<Unit filename="network_manager.hpp" />
<Unit filename="protocol.cpp" />
<Unit filename="protocol.hpp" />
<Unit filename="protocol_listener.hpp" />
<Unit filename="protocol_manager.cpp" />
<Unit filename="protocol_manager.hpp" />
<Unit filename="protocols/connect_to_server.cpp" />
<Unit filename="protocols/connect_to_server.hpp" />
<Unit filename="protocols/get_public_address.cpp" />
<Unit filename="protocols/get_public_address.hpp" />
<Unit filename="server_network_manager.cpp" />
<Unit filename="server_network_manager.hpp" />
<Unit filename="singleton.hpp" />
<Unit filename="stk_host.cpp" />
<Unit filename="stk_host.hpp" />
<Unit filename="stk_peer.cpp" />
<Unit filename="stk_peer.hpp" />
<Extensions>
<code_completion />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -4,12 +4,46 @@
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
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()

View File

@ -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 <stdio.h>
#include <string.h>
@ -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)

View File

@ -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;
}

View File

@ -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<STKPeer*> m_peers;
STKHost* m_localhost;

View File

@ -0,0 +1,80 @@
#include "connect_to_server.hpp"
#include "../http_functions.hpp"
#include <stdio.h>
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;
}

View File

@ -0,0 +1,37 @@
#ifndef CONNECT_TO_SERVER_HPP
#define CONNECT_TO_SERVER_HPP
#include "../protocol.hpp"
#include <string>
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

View File

@ -1,6 +1,7 @@
#include "get_public_address.hpp"
#include "../network_manager.hpp"
#include "connect_to_server.hpp"
#include <time.h>
#include <stdlib.h>
@ -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<ConnectToServer*>(m_callbackObject);
cbObj->setSelfAddress(address, port);
m_listener->runProtocol(cbObj);
}
else
m_state = NOTHING_DONE; // need to re-send the stun request

View File

@ -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);