Ejemplo n.º 1
0
/**
 *  prüft auf neue Clients.
 *
 *  @author FloSoft
 */
bool LobbyServer::CheckForNewClients()
{
    SocketSet set;

    set.Add(serverSock_);
    if( set.Select(0, 0) > 0)
    {
        if(set.InSet(serverSock_))
        {
            Socket client = serverSock_.Accept();
            if(!client.isValid())
                return false;

            unsigned playerid = static_cast<unsigned>(players.size());
            while(players.find(playerid) != players.end())
                ++playerid;

            LOG.write("New client connected from %s\n") % client.GetPeerIP();

            LobbyPlayer p;

            p.attach(client, playerid);

            players[playerid] = p;

            LOG.write("Player-ID %d\n") % playerid;

            p.Send(new LobbyMessage_Id(playerid), true);
        }
    }
    return true;
}
Ejemplo n.º 2
0
void SocketServer::service() {
  // Add listeners
  SocketSet sockSet;
  for (unsigned i = 0; i < ports.size(); i++)
    sockSet.add(ports[i]->socket, SocketSet::READ);

  // Add others
  addConnectionSockets(sockSet);

  if (sockSet.select(0.1) || connectionsReady()) {
    // Process connections
    processConnections(sockSet);

    // Accept new connections
    for (unsigned i = 0; i < ports.size() && !shouldShutdown(); i++) {
      try {
        Socket &socket = ports[i]->socket;

        if (!sockSet.isSet(socket, SocketSet::READ)) continue;

        IPAddress clientIP;
        while (true) {
          SmartPointer<Socket> client = socket.accept(&clientIP);
          if (client.isNull()) break;

          // Check access
          if (!allow(clientIP.getIP())) {
            LOG_INFO(3, "Server access denied for " << clientIP);
            continue;
          }

          SocketConnectionPtr con = createConnection(client, clientIP);
          client = 0; // Release socket pointer

          if (con.isNull())
            LOG_INFO(3, "Dropped server connection on "
                     << ports[i]->ip << " from " << clientIP);

          else {
            connections.push_back(con);

            LOG_INFO(3, "Server connection id=" << con->getID() << " on "
                     << ports[i]->ip << " from "
                     << IPAddress(clientIP.getIP()));
          }
        }
      } CBANG_CATCH_ERROR;
    }
  }
Ejemplo n.º 3
0
/**
 *  Hauptschleife.
 *
 *  @author FloSoft
 */
void LobbyClient::Run(void)
{
    if(state == CS_STOPPED)
        return;

    SocketSet set;

    // erstmal auf Daten überprüfen
    set.Clear();

    // zum set hinzufügen
    set.Add(socket);
    if(set.Select(0, 0) > 0)
    {
        // nachricht empfangen
        if(!recv_queue.recv(socket))
        {
            LOG.lprintf("Receiving Message from server failed\n");
            ServerLost();
            return;
        }
    }

    // nun auf Fehler prüfen
    set.Clear();

    // zum set hinzufügen
    set.Add(socket);

    // auf fehler prüfen
    if(set.Select(0, 2) > 0)
    {
        if(set.InSet(socket))
        {
            // Server ist weg
            LOG.lprintf("Error on socket to server\n");
            ServerLost();
            return;
        }
    }

    // maximal 10 Pakete verschicken
    if(!send_queue.send(socket, 10))
    {
        ServerLost();
        return;
    }

    // recv-queue abarbeiten
    while(recv_queue.count() > 0)
    {
        recv_queue.front()->run(this, 0xFFFFFFFF);
        recv_queue.pop();
    }
}
Ejemplo n.º 4
0
void Server::addConnectionSockets(SocketSet &sockSet) {
  SocketServer::addConnectionSockets(sockSet);

  for (iterator it = begin(); it != end(); it++) {
    Connection &con = *it->castPtr<Connection>();

    switch (con.getState()) {
    case Connection::READING_HEADER:
    case Connection::READING_DATA:
      sockSet.add(con.getSocket(), SocketSet::READ);
      break;

    case Connection::WRITING_HEADER:
    case Connection::WRITING_DATA:
      if (!con.getContext() || con.getContext()->isReady())
        sockSet.add(con.getSocket(), SocketSet::WRITE);
      break;

    default: break;
    }
  }
}
Ejemplo n.º 5
0
int main()
{
    Socket server(SockType::TCP);
    server.SetReuseAddr(true);
    server.SetBlocking(false);
    server.Bind(IpAddress("127.0.0.1:8999"));
    server.Listen(100);

    SocketSet Rs;
    Rs.Add(&server);
    SocketSet Ws;
    while (true)
    {
        int nRet = SocketSet::Select(Rs, Ws, 1000);
        if (nRet > 0)
        {
            for (auto R : Rs)
            {
                IpAddress Ip(nullptr);
                if (R == &server)
                {
                    Socket* C = R->Accept(Ip);
                    if (C)
                    {
                        Rs.Add(C);
                    }
                }
                else
                {
                    char Buffer[1024] = { 0 };
                    int Recv = R->Receive(Buffer, 1024);
                    if (Recv>0)
                        printf("kkkkk: R %s\n", Buffer);
                }
            }
        }
    }
}
Ejemplo n.º 6
0
void Server::processConnections(SocketSet &sockSet) {
  if (!initialized) THROW("HTTP::Server not initialized");

  // Save current thread ID and restore it before leaving this scope
  struct SmartThreadID {
    unsigned threadID;
    SmartThreadID() : threadID(Logger::instance().getThreadID()) {}
    ~SmartThreadID() {Logger::instance().setThreadID(threadID);}
  } smartThreadID;

  for (iterator it = begin(); it != end() && !shouldShutdown(); it++) {
    // Set thread ID = connection ID
    Logger::instance().setThreadID((*it)->getID());
    processConnection(*it, sockSet.isSet((*it)->getSocket()));
  }
}
Ejemplo n.º 7
0
/**
 *
 *
 *  @author FloSoft
 */
Message* Message::recv(Socket& sock, int& error, bool wait, Message * (*createfunction)(unsigned short))
{
    error = -1;

    unser_time_t time = TIME.CurrentTick();

    unser_time_t timeout = time;
    unsigned int received;
    SocketSet set;

    while(true)
    {
        // Warten wir schon 5s auf Antwort?
        if(time - timeout > 15000)
            wait = false;

        time = TIME.CurrentTick();

        // SocketSet "saubermachen"
        set.Clear();

        // Socket hinzufgen
        set.Add(sock);

        // liegen Daten an?
        int retval = set.Select(0, 0);

        if(retval <= 0)
        {
            if(wait)
                continue;

            if(retval != -1)
                error = 0;

            return NULL;
        }

        // liegen diese Daten an unserem Socket, bzw wieviele Bytes liegen an?
        if(!set.InSet(sock) || sock.BytesWaiting(&received) != 0)
        {
            if(wait)
                continue;

            error = 1;
            return NULL;
        }

        // socket ist geschlossen worden
        if(received == 0)
            return NULL;

        // haben wir schon eine vollständige nachricht? (kleinste nachricht: 6 bytes)
        if(received < 6)
        {
            if(wait)
                continue;

            error = 2;
            return NULL;
        }
        break;
    }

    int read = -1;

    char block[6];
    unsigned short* id = (unsigned short*)&block[0];
    unsigned int* length = (unsigned int*)&block[2];

    // block empfangen
    read = sock.Recv(block, 6, false);
    if(read != 6)
    {
        LOG.write("recv: block: only got %d bytes instead of %d, waiting for next try\n", read, 6);
        if(read != -1)
            error = 3;

        return NULL;
    }

    read = sock.BytesWaiting();

    static unsigned int blocktimeout = 0;
    if(read < (signed)((*length) + 6) )
    {
        ++blocktimeout;
        LOG.write("recv: block-waiting: not enough input (%d/%d) for message (0x%04X), waiting for next try\n", read, (*length) + 6, *id);
        if(blocktimeout < 120 && read != -1)
            error = 4;

        return NULL;
    }
    blocktimeout = 0;

    // Block nochmals abrufen (um ihn aus dem Cache zu entfernen)
    read = sock.Recv(block, 6);
    if(read != 6)
    {
        LOG.lprintf("recv: id,length: only got %d bytes instead of %d\n", read, 2);
        return NULL;
    }

    Message* msg = createfunction(*id);
    if(!msg)
        return NULL;

    // Daten abrufen
    msg->recv(sock, *length);

    return msg;
}
Ejemplo n.º 8
0
/**
 *  verarbeitet alle Nachrichten der Clients.
 *
 *  @author FloSoft
 */
bool LobbyServer::ProcessMessages()
{
    SocketSet set;

    // In einem SocketSet alle Clients hinzufügen und gucken, ob etwas empfangen wurde
    for(LobbyPlayerMapIterator it = players.begin(); it != players.end(); ++it)
    {
        LobbyPlayer& p = it->second;

        if(!p.isFree())
            p.addToSet(set);
    }

    if(set.Select(0, 0) > 0)
    {
        for(LobbyPlayerMapIterator it = players.begin(); it != players.end(); ++it)
        {
            LobbyPlayer& p = it->second;

            if(p.inSet(set) && !p.Receive())
                Disconnect(p);
        }
    }

    set.Clear();

    // In einem SocketSet alle Clients hinzufügen und gucken, ob fehler aufgetreten sind
    for(LobbyPlayerMapIterator it = players.begin(); it != players.end(); ++it)
    {
        LobbyPlayer& p = it->second;

        if(!p.isFree())
            p.addToSet(set);
    }

    if(set.Select(0, 2) > 0)
    {
        LOG.write("Error on Sockets\n");

        for(LobbyPlayerMapIterator it = players.begin(); it != players.end(); ++it)
        {
            LobbyPlayer& p = it->second;

            if( p.inSet(set) )
            {
                LOG.write("Player %d: Connection lost\n") % p.getId();
                Disconnect(p);
            }
        }
    }

    // Nachrichten-Queues der Spieler abschicken (max 10 Nachrichten pro Spieler pro Runde)
    for(LobbyPlayerMapIterator it = players.begin(); it != players.end(); ++it)
    {
        LobbyPlayer& p = it->second;

        if(!p.Send())
            Disconnect(p);
        else
            p.Run(this);
    }

    return true;
}
Ejemplo n.º 9
0
void Waitable::wait(int timeout)
{
    SocketSet set;
    set.add(this);
    set.wait(timeout);
}
Ejemplo n.º 10
0
int main(int argc, char ** argv)
{
	string data;
	stringstream buf;
	unsigned int i;
	
	Stats stats;
	ClientSet clients;
	SocketSet sockets;
	Switchboard switchboard;
	ArgumentSet arguments(argc, argv);

	if (arguments.isset("version") || arguments.isset("v"))
	{
		cout << PACKAGE_NAME << " version " << PACKAGE_VERSION << endl;
		return 0;
	}
	
	if (arguments.isset("help") || arguments.isset("h"))
	{
		cout << endl;
		cout << "usage: istatd [-a HOST] [-p PORT]" << endl;
		cout << endl;
		cout << "    -d                 run in background" << endl;
		cout << "    -h                 print this help text" << endl;
		cout << "    -v                 print version number" << endl;
		cout << endl;
		cout << "    -c FILE            custom config file location" << endl;
		cout << "    -a HOST            listen on this address" << endl;
		cout << "    -p PORT            listen on this port" << endl;
		cout << "    -u USER            change running user" << endl;
		cout << "    -g GROUP           change running group" << endl;
		cout << endl;
		cout << "    --pid=FILE         custom pid file location" << endl;
		cout << "    --cache=DIR        custom cache file location" << endl;
		cout << "    --socket=FILE      custom socket file location" << endl;
		cout << "    --code=CODE        custom lock code" << endl;
		cout << endl;
		return 0;
	}
	
	// Load and parse configuration
	Config config(arguments.get("c", CONFIG_FILE_PATH));
	
	config.parse();
	config.validate();
	
	// Load configuration properties from command line and config file
	bool arg_d = arguments.isset("d");
	string cf_network_addr = arguments.get("a", config.get("network_addr", "0.0.0.0"));
	string cf_network_port = arguments.get("p", config.get("network_port", "5109"));
	string cf_server_user = arguments.get("u", config.get("server_user", "istat"));
	string cf_server_group = arguments.get("g", config.get("server_group", "istat"));
	string cf_server_pid = arguments.get("pid", config.get("server_pid", ""));
	string cf_cache_dir = arguments.get("cache", config.get("cache_dir", "/var/cache/istat"));
	string cf_server_socket = arguments.get("socket", config.get("server_socket", "/tmp/istatd.sock"));
   
#ifdef HAVE_LIBKSTAT
	if(-1 == kstat_init()) return 1;
#endif
	
	Daemon unixdaemon(cf_server_pid, cf_server_socket, cf_cache_dir);
	Socket listener(cf_network_addr, to_int(cf_network_port));
	SignalResponder signalresponder(&sockets, &listener, &unixdaemon, &clients);
	
	::pn_signalresponder = &signalresponder;

	// Create socket, pid file and put in background if desired
	unixdaemon.create(arg_d, cf_server_user, cf_server_group);
	
	// Get old sessions from disk cache
	clients.read_cache(cf_cache_dir);
	
	// Clear cache of saved sessions
	if (arguments.isset("clear-sessions"))
	{
		clients.clear_cache();
		return 0;
	}

	signal(SIGHUP,  handler);
	signal(SIGUSR1, handler);
	signal(SIGINT,  handler);
	signal(SIGTERM, handler);
	signal(SIGPIPE, handler);

	if (!listener.listen()) return 1;
	
	sockets += listener;
	
	// Add disks for monitoring
	if (config.get("monitor_disk") != "")
	{
		// No array found. Add value given.
		stats.add_disk(config.get("monitor_disk").c_str());
	}
	else
	{
		// Array found. Add all values in the array.
		for (i = 0; i < config.get_property("monitor_disk").get_array_size(); i++)
		{
			stats.add_disk(config.get_property("monitor_disk").get_array(i).c_str());
		}
	}
	
	// Add network interfaces for monitoring
	if (config.get("monitor_net") != "")
	{
		// No array found. Add value given.
		stats.add_net(config.get("monitor_net").c_str());
	}
	else
	{
		// Array found. Add all values in the array.
		for (i = 0; i < config.get_property("monitor_net").get_array_size(); i++)
		{
			stats.add_net(config.get_property("monitor_net").get_array(i).c_str());
		}
	}
	
#ifdef HAVE_LIBSENSORS
	unsigned int sensor_num;
	struct sensor_data sensor_data;

	sensor_num = get_sensor_num();
	
	for (i = 0; i < sensor_num; i++)
	{
		get_sensor_data(i, &sensor_data);
		
		stats.add_sensor(&sensor_data);
	}
#endif

#ifdef  HAVE_QNAPTEMP
	struct sensor_data sensor_data;
	if (have_qnaptemp()) {
		get_qnaptemp(0, &sensor_data);
		stats.add_sensor(&sensor_data);
	}
#endif

	while (1)
	{
		stats.update_system_stats();
		
		if (sockets.get_status(1))
		{
			if (sockets == listener)
			{
				Socket new_socket(listener.accept());
				
				sockets += new_socket;
			}
			else
			{
				Socket active_socket(sockets.get_ready());
		
				if (active_socket.receive(data, 1024))
				{
					switchboard.parse(&sockets, &clients, &config, &active_socket, &stats, &arguments, data);
				}
				else
				{
					sockets -= active_socket;
				}
			}
		}
	}
	
	::pn_signalresponder = NULL;
	
	return 0;
}