Beispiel #1
0
/**
 * @param socket  Socket to communicate over
 * @param type    Command ID
 * @param source  Source ID
 * @param len     Data length
 * @param content Payload
 * @return 0 on success
 */
    int SendMessage(SWInetSocket *socket, int type, int source, unsigned int streamid, unsigned int len,
                    const char *content) {
        assert(socket != nullptr);

        SWBaseSocket::SWBaseError error;
        RoRnet::Header head;

        const int msgsize = sizeof(RoRnet::Header) + len;

        if (msgsize >= RORNET_MAX_MESSAGE_LENGTH) {
            Logger::Log(LOG_ERROR, "UID: %d - attempt to send too long message", source);
            return -4;
        }

        char buffer[RORNET_MAX_MESSAGE_LENGTH];

        memset(&head, 0, sizeof(RoRnet::Header));
        head.command = type;
        head.source = source;
        head.size = len;
        head.streamid = streamid;

        // construct buffer
        memset(buffer, 0, RORNET_MAX_MESSAGE_LENGTH);
        memcpy(buffer, (char *) &head, sizeof(RoRnet::Header));
        memcpy(buffer + sizeof(RoRnet::Header), content, len);

        if (socket->fsend(buffer, msgsize, &error) < msgsize)
        {
            Logger::Log(LOG_ERROR, "send error -1: %s", error.get_error().c_str());
            return -1;
        }
        StatsAddOutgoing(msgsize);
        return 0;
    }
Beispiel #2
0
/**
 * @param socket socket to communicate over
 * @param type a type... dunno
 * @param source who is sending the message
 * @param len length of the content being sent
 * @param content message to send
 * @return dunno
 */
int Messaging::sendmessage(SWInetSocket *socket, int type, int source, unsigned int streamid, unsigned int len, const char* content)
{
    STACKLOG;
    if( NULL == socket )
    {
    	Logger::log( LOG_ERROR, "UID: %d - attempt to send a messaage over a"
    			"null socket.", source );
    	return -3;
    }
    //SWInetSocket* socket = Sequencer::getSocket(source)
	SWBaseSocket::SWBaseError error;
	header_t head;

	const int msgsize = sizeof(header_t) + len;

	if(msgsize >= MAX_MESSAGE_LENGTH)
	{
    	Logger::log( LOG_ERROR, "UID: %d - attempt to send too long message", source);
    	return -4;
	}

	char buffer[MAX_MESSAGE_LENGTH];
	

	int rlen = 0;
	
	memset(&head, 0, sizeof(header_t));
	head.command  = type;
	head.source   = source;
	head.size     = len;
	head.streamid = streamid;
	
	// construct buffer
	memset(buffer, 0, MAX_MESSAGE_LENGTH);
	memcpy(buffer, (char *)&head, sizeof(header_t));
	memcpy(buffer + sizeof(header_t), content, len);

#if 0
	// comment out since this severly bloats the server log
	char body[len*2+1];
	memset( body, 0,len*2+1);
	bodyblockashex(body, content, len);
	Logger::log( LOG_DEBUG, "sending message:  \t%d\t%d\t%d", type, source, len);
	Logger::log( LOG_DEBUG, "%s", body);
#endif
	while (rlen < msgsize)
	{
		int sendnum = socket->send( buffer + rlen, msgsize - rlen, &error );
		if (sendnum < 0 || error != SWBaseSocket::ok) 
		{
			Logger::log(LOG_ERROR, "send error -1: %s", error.get_error().c_str());
			return -1;
		}
		rlen += sendnum;
	}
	//Logger::log(LOG_DEBUG, "message of size %d sent to uid %d.", rlen, source);
	traffic.bandwidthOutgoing += msgsize;
	return 0;
}
Beispiel #3
0
int Notifier::HTTPPOST(const char* URL, const char* data)
{
    STACKLOG;
	int res=0;
	SWBaseSocket::SWBaseError error;
	SWInetSocket mySocket;

	if (mySocket.connect(80, REPO_SERVER, &error))
	{
		char query[2048];
		int len = (int)strnlen(data, 16000);
		sprintf(query, "POST %s HTTP/1.0\r\n" \
		               "Host: %s\r\n" \
					   "Content-Type: application/octet-stream\r\n" \
					   "Content-Length: %d\r\n"
					   "\r\n" \
					   "%s", \
					   URL, REPO_SERVER, len, data);
		Logger::log(LOG_DEBUG,"Query to Master server: %s", query);
		if (mySocket.sendmsg(query, &error)<0)
		{
			Logger::log(LOG_ERROR,"Notifier: could not send request (%s)", error.get_error().c_str());
			res=-1;
		}
		int rlen=mySocket.recv(httpresp, 65536, &error);
		
		
		if (rlen>0 && rlen<65535) httpresp[rlen]=0;
		else
		{
			Logger::log(LOG_ERROR,"Notifier: could not get a valid response (%s)",
					error.get_error().c_str());
			res=-1;
		}
		Logger::log(LOG_DEBUG,"Response from Master server:'%s'", httpresp);
		try
		{
			resp = HttpMsg(httpresp);
		}
		catch( std::runtime_error e)
		{
			Logger::log(LOG_ERROR, e.what() );
			res = -1;
		}
		
		// disconnect
		mySocket.disconnect();
	}
	else
	{
		Logger::log(LOG_ERROR,"Notifier: could not connect to the Master server (%s)", error.get_error().c_str());
		res=-1;
	}
	return res;
}
int UserAuth::HTTPGET(const char* URL, HttpMsg &resp)
{
    STACKLOG;
	
	if(trustlevel<=1)
	{
		// If this happens, then you did something wrong in the server code
		Logger::log(LOG_ERROR, "userauth: tried to contact master server without permission. URL: %s", URL);
		return 0;
	}
	
	char httpresp[65536];  //!< http response from the master server
	int res=0;
	SWBaseSocket::SWBaseError error;
	SWInetSocket mySocket;

	if (mySocket.connect(80, REPO_SERVER, &error))
	{
		char query[2048];
		sprintf(query, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", URL, REPO_SERVER);
		Logger::log(LOG_DEBUG,"Query to Master server: %s", query);
		if (mySocket.sendmsg(query, &error)<0)
		{
			Logger::log(LOG_ERROR,"Notifier: could not send request (%s)", error.get_error().c_str());
			res=-1;
		}
		int rlen=mySocket.recv(httpresp, 65536, &error);
		if (rlen>0 && rlen<65535) httpresp[rlen]=0;
		else
		{
			Logger::log(LOG_ERROR,"Notifier: could not get a valid response (%s)", error.get_error().c_str());
			res=-1;
		}
		Logger::log(LOG_DEBUG,"Response from Master server:'%s'", httpresp);
		try
		{
			resp = HttpMsg(httpresp);
		}
		catch( std::runtime_error e)
		{
			Logger::log(LOG_ERROR, e.what() );
			res = -1;
		}
		// disconnect
		mySocket.disconnect();
	}
	else
	{
		Logger::log(LOG_ERROR,"Notifier: could not connect to the Master server (%s)", error.get_error().c_str());
		res=-1;
	}
	return res;
}
Beispiel #5
0
int Notifier::HTTPGET(const char* URL)
{
    STACKLOG;
	int res=0;
	SWBaseSocket::SWBaseError error;
	SWInetSocket mySocket;

	if (mySocket.connect(80, REPO_SERVER, &error))
	{
		char query[2048];
		sprintf(query, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", URL, REPO_SERVER);
		Logger::log(LOG_DEBUG,"Query to Master server: %s", query);
		if (mySocket.sendmsg(query, &error)<0)
		{
			Logger::log(LOG_ERROR,"Notifier: could not send request (%s)", error.get_error().c_str());
			res=-1;
		}
		int rlen=mySocket.recv(httpresp, 65536, &error);
		if (rlen>0 && rlen<65535) httpresp[rlen]=0;
		else
		{
			Logger::log(LOG_ERROR,"Notifier: could not get a valid response (%s)", error.get_error().c_str());
			res=-1;
		}
		Logger::log(LOG_DEBUG,"Response from Master server:'%s'", httpresp);
		try
		{
			resp = HttpMsg(httpresp);
		}
		catch( std::runtime_error e)
		{
			Logger::log(LOG_ERROR, e.what() );
			res = -1;
		}
		// disconnect
		mySocket.disconnect();
	}
	else
	{
		Logger::log(LOG_ERROR,"Notifier: could not connect to the Master server (%s)", error.get_error().c_str());
		res=-1;
	}
	return res;
}
Beispiel #6
0
void Listener::threadstart() {
    Logger::Log(LOG_DEBUG, "Listerer thread starting");
    //here we start
    SWBaseSocket::SWBaseError error;

    //manage the listening socket
    m_listen_socket.bind(m_listen_port, &error);
    if (error != SWBaseSocket::ok) {
        //this is an error!
        Logger::Log(LOG_ERROR, "FATAL Listerer: %s", error.get_error().c_str());
        //there is nothing we can do here
        return;
        // exit(1);
    }
    m_listen_socket.listen();

    Logger::Log(LOG_VERBOSE, "Listener ready");
    m_ready_cond.Signal(1);

    //await connections
    while (!m_thread_shutdown) {
        Logger::Log(LOG_VERBOSE, "Listener awaiting connections");
        SWInetSocket *ts = (SWInetSocket *) m_listen_socket.accept(&error);

        if (error != SWBaseSocket::ok) {
            if (m_thread_shutdown) {
                Logger::Log(LOG_ERROR, "INFO Listener shutting down");
            } else {
                Logger::Log(LOG_ERROR, "ERROR Listener: %s", error.get_error().c_str());
            }
        }

        Logger::Log(LOG_VERBOSE, "Listener got a new connection");

        ts->set_timeout(5, 0);

        //receive a magic
        int type;
        int source;
        unsigned int len;
        unsigned int streamid;
        char buffer[RORNET_MAX_MESSAGE_LENGTH];

        try {
            // this is the start of it all, it all starts with a simple hello
            if (Messaging::ReceiveMessage(ts, &type, &source, &streamid, &len, buffer, RORNET_MAX_MESSAGE_LENGTH))
                throw std::runtime_error("ERROR Listener: receiving first message");

            // make sure our first message is a hello message
            if (type != RoRnet::MSG2_HELLO) {
                Messaging::SendMessage(ts, RoRnet::MSG2_WRONG_VER, 0, 0, 0, 0);
                throw std::runtime_error("ERROR Listener: protocol error");
            }

            // check client version
            if (source == 5000 && (std::string(buffer) == "MasterServer")) {
                Logger::Log(LOG_VERBOSE, "Master Server knocked ...");
                // send back some information, then close socket
                char tmp[2048] = "";
                sprintf(tmp, "protocol:%s\nrev:%s\nbuild_on:%s_%s\n", RORNET_VERSION, VERSION, __DATE__, __TIME__);
                if (Messaging::SendMessage(ts, RoRnet::MSG2_MASTERINFO, 0, 0, (unsigned int) strlen(tmp), tmp)) {
                    throw std::runtime_error("ERROR Listener: sending master info");
                }
                // close socket
                ts->disconnect(&error);
                delete ts;
                continue;
            }

            // compare the versions if they are compatible
            if (strncmp(buffer, RORNET_VERSION, strlen(RORNET_VERSION))) {
                // not compatible
                Messaging::SendMessage(ts, RoRnet::MSG2_WRONG_VER, 0, 0, 0, 0);
                throw std::runtime_error("ERROR Listener: bad version: " + std::string(buffer) + ". rejecting ...");
            }

            // compatible version, continue to send server settings
            std::string motd_str;
            {
                std::vector<std::string> lines;
                if (!Utils::ReadLinesFromFile(Config::getMOTDFile(), lines))
                {
                    for (const auto& line : lines)
                        motd_str += line + "\n";
                }
            }

            Logger::Log(LOG_DEBUG, "Listener sending server settings");
            RoRnet::ServerInfo settings;
            memset(&settings, 0, sizeof(RoRnet::ServerInfo));
            settings.has_password = !Config::getPublicPassword().empty();
            strncpy(settings.info, motd_str.c_str(), motd_str.size());
            strncpy(settings.protocolversion, RORNET_VERSION, strlen(RORNET_VERSION));
            strncpy(settings.servername, Config::getServerName().c_str(), Config::getServerName().size());
            strncpy(settings.terrain, Config::getTerrainName().c_str(), Config::getTerrainName().size());

            if (Messaging::SendMessage(ts, RoRnet::MSG2_HELLO, 0, 0, (unsigned int) sizeof(RoRnet::ServerInfo),
                                       (char *) &settings))
                throw std::runtime_error("ERROR Listener: sending version");

            //receive user infos
            if (Messaging::ReceiveMessage(ts, &type, &source, &streamid, &len, buffer, RORNET_MAX_MESSAGE_LENGTH)) {
                std::stringstream error_msg;
                error_msg << "ERROR Listener: receiving user infos\n"
                          << "ERROR Listener: got that: "
                          << type;
                throw std::runtime_error(error_msg.str());
            }

            if (type != RoRnet::MSG2_USER_INFO)
                throw std::runtime_error("Warning Listener: no user name");

            if (len > sizeof(RoRnet::UserInfo))
                throw std::runtime_error("Error: did not receive proper user credentials");
            Logger::Log(LOG_INFO, "Listener creating a new client...");

            RoRnet::UserInfo *user = (RoRnet::UserInfo *) buffer;
            user->authstatus = RoRnet::AUTH_NONE;

            // authenticate
            user->username[RORNET_MAX_USERNAME_LEN - 1] = 0;
            std::string nickname = Str::SanitizeUtf8(user->username);
            user->authstatus = m_sequencer->AuthorizeNick(std::string(user->usertoken, 40), nickname);
            strncpy(user->username, nickname.c_str(), RORNET_MAX_USERNAME_LEN - 1);

            if (Config::isPublic()) {
                Logger::Log(LOG_DEBUG, "password login: %s == %s?",
                            Config::getPublicPassword().c_str(),
                            std::string(user->serverpassword, 40).c_str());
                if (strncmp(Config::getPublicPassword().c_str(), user->serverpassword, 40)) {
                    Messaging::SendMessage(ts, RoRnet::MSG2_WRONG_PW, 0, 0, 0, 0);
                    throw std::runtime_error("ERROR Listener: wrong password");
                }

                Logger::Log(LOG_DEBUG, "user used the correct password, "
                        "creating client!");
            } else {
                Logger::Log(LOG_DEBUG, "no password protection, creating client");
            }

            //create a new client
            m_sequencer->createClient(ts, *user); // copy the user info, since the buffer will be cleared soon
            Logger::Log(LOG_DEBUG, "listener returned!");
        }
        catch (std::runtime_error &e) {
            Logger::Log(LOG_ERROR, e.what());
            ts->disconnect(&error);
            delete ts;
        }
    }
}
Beispiel #7
0
/**
 * @param out_type        Message type, see MSG2_* macros in rornet.h
 * @param out_source      Magic. Value 5000 used by serverlist to check this server.
 * @return                0 on success, negative number on error.
 */
int Messaging::receivemessage(
		SWInetSocket *socket,
		int* out_type,
		int* out_source,
		unsigned int* out_stream_id,
		unsigned int* out_payload_len,
		char* out_payload,
		unsigned int payload_buf_len)
{
	STACKLOG;

	assert(socket        != nullptr);
	assert(out_type      != nullptr);
	assert(out_source    != nullptr);
	assert(out_stream_id != nullptr);
	assert(out_payload   != nullptr);

	char buffer[MAX_MESSAGE_LENGTH] = {};
	
	int hlen=0;
	SWBaseSocket::SWBaseError error;
	while (hlen<(int)sizeof(header_t))
	{
		int recvnum=socket->recv(buffer+hlen, sizeof(header_t)-hlen, &error);
		if (recvnum < 0 || error!=SWBaseSocket::ok)
		{
			Logger::log(LOG_ERROR, "receive error -2: %s", error.get_error().c_str());
			// this also happens when the connection is canceled
			return -2;
		}
		hlen+=recvnum;
	}

	header_t head;
	memcpy(&head, buffer, sizeof(header_t));
	*out_type         = head.command;
	*out_source       = head.source;
	*out_payload_len  = head.size;
	*out_stream_id    = head.streamid;
	
	if((int)head.size >= MAX_MESSAGE_LENGTH)
	{
		Logger::log(LOG_ERROR, "receivemessage(): payload too long: %d b (max. is %d b)", head.size, MAX_MESSAGE_LENGTH);
		return -3;
	}

	if( head.size > 0)
	{
		//read the rest
		while (hlen < (int)sizeof(header_t) + (int)head.size)
		{
			int recvnum = socket->recv(buffer + hlen,
					(head.size+sizeof(header_t)) - hlen, &error);
			if (recvnum<0 || error!=SWBaseSocket::ok)
			{
				Logger::log(LOG_ERROR, "receive error -1: %s",
						error.get_error().c_str());
				return -1;
			}
			hlen += recvnum;
		}
	}

	traffic.bandwidthIncoming += (int)sizeof(header_t)+(int)head.size;
	memcpy(out_payload, buffer+sizeof(header_t), payload_buf_len);
	return 0;
}