コード例 #1
0
void KeyValueStore::InternalThread::incomingRoutine()
{
  const Config::ServerInformation& info = config.getServerInformation();
  Config::ThreadControl& control = config.getThreadControl();
  Mutex& inMutex = control.getInMutex();
  Condition& cond = control.getInCondition();
  Thread incoming;
  Incoming inTask;
  int currId = -1;
  static bool first = true;

  // Init connection info
  SocketAddress sock(info.address, info.internalPort);
  ServerSocket server;
  try {
    server.bind(sock, true);
    server.listen(5);
  } catch(Exception& e) {
    printKv("Could not initialize internal thread, please restart server ("<< e.displayText()<< ")");
  }

  StreamSocket client;

  while(control.isLive()) {
    inMutex.lock();
    cond.wait(inMutex);
    unsigned nextId = control.getConnectedId();
    inMutex.unlock();

    // NOTE: From a security perspective this is not safe.
    //  if someone tries to connect at the same time a rejoin
    //  was initiated, they could easily perform a MITM attack.
    //  However, since this is an academic exercise, I am not too
    //  concerned with security (as can be seen by many other components
    //  in this system as well).
    if(currId != (int)nextId) {
      currId = nextId;
      // TODO: Update processing thread somehow
      printKv("Told a new server should be connecting...");
      try {
        client = server.acceptConnection();
        printKv("Incoming server connected: "<< currId);
        inTask.cancel();
        if(!first)
          incoming.join();
        first = false;
        inTask = Incoming(client, &config.getThreadControl());
        incoming.start(inTask);
        printKv("Handling new server");
      } catch(TimeoutException& e) {
        printKv("Server did not connect in time - we don't want the system to be hung up, though ("<< e.displayText() <<")");
      }
    }
  }

  server.close();
}
コード例 #2
0
        virtual void run(){
            try{
                unsigned char buf[1000];

                ServerSocket server;
                server.bind( "127.0.0.1", SocketFactoryTest::DEFAULT_PORT );

                net::Socket* socket = server.accept();
                server.close();

                socket->setSoLinger( false, 0 );

                synchronized(&mutex)
                {
                    numClients++;
                    mutex.notifyAll();
                }

                while( !done && socket != NULL ){

                    io::InputStream* stream = socket->getInputStream();
                    memset( buf, 0, 1000 );
                    try{
                        if( stream->read( buf, 1000, 0, 1000 ) == -1 ) {
                            done = true;
                            continue;
                        }

                        lastMessage = (char*)buf;

                        if( strcmp( (char*)buf, "reply" ) == 0 ){
                            io::OutputStream* output = socket->getOutputStream();
                            output->write( (unsigned char*)"hello", (int)strlen("hello"), 0, (int)strlen("hello") );
                        }

                    }catch( io::IOException& ex ){
                        done = true;
                    }
                }

                socket->close();
                delete socket;

                numClients--;

                synchronized(&mutex) {
                    mutex.notifyAll();
                }

            }catch( io::IOException& ex ){
                printf("%s\n", ex.getMessage().c_str() );
                CPPUNIT_ASSERT( false );
            }catch( ... ){
                CPPUNIT_ASSERT( false );
            }
        }
コード例 #3
0
ファイル: main.cpp プロジェクト: captgreen1/Speedi
int main(int argc, const char * argv[]) {
	
	ServerSocket mainSocket = ServerSocket(4444);
	
	Socket socket = mainSocket.acceptConnection();
	
	socket.beginHandling();
	
	socket.closeSocket();
	mainSocket.close();
	
    return 0;
}
コード例 #4
0
/** Public thread methods (clients connect here) */
void KeyValueStore::PublicThread::run()
{
  Thread threads[MAX_CLIENT_THREADS];
  HandleClient threadInst[MAX_CLIENT_THREADS];
  const Config::ServerInformation& info = config.getServerInformation();
  Config::ThreadControl& control = config.getThreadControl();
  int id = 0;
  char full = Protocol::SRV_FULL;
  char conn = Protocol::SRV_CONN;

  ServerSocket server;
  SocketAddress sock(info.address, info.pubPort);
  server.bind(sock, true);
  server.listen(5);

  printKv("Listening for clients on "<< info.address <<":"<< info.pubPort);

  while(control.isLive()) {
    // Simply do thread per client
    StreamSocket client = server.acceptConnection();
    printKv("Received client connection request - waiting for thread to free up");
    
    // Wait five seconds
    try {
      freeThreads.wait(5000); // This beats busy waiting
    } catch(TimeoutException& notUsed(e)) {
      printKv("Server full - closing connection to client");
      client.sendBytes(&full, sizeof(full));
      client.close();
      continue;
    }

    // Send success
    client.sendBytes(&conn, sizeof(conn));

    // tryJoin() doesn't work properly in linux, using isRunning() instead
    // actively search for the next available thread
    while(threads[id].isRunning()){ // Try to get an available thread
      id = (id + 1) % MAX_CLIENT_THREADS;
      Thread::sleep(250); // 250ms between each check
    }

    printKv("Serving client");
    threadInst[id] = HandleClient(client, control);
    threads[id].start(threadInst[id]);
  }

  server.close();
  freeThreads.set(); // Free a thread with semaphore
}
コード例 #5
0
void SocketTest::testConnectRefused()
{
	ServerSocket serv;
	serv.bind(SocketAddress());
	serv.listen();
	Poco::UInt16 port = serv.address().port();
	serv.close();
	StreamSocket ss;
	Timespan timeout(250000);
	try
	{
		ss.connect(SocketAddress("localhost", port));
		fail("connection refused - must throw");
	}
	catch (ConnectionRefusedException&)
	{
	}
}
コード例 #6
0
void LocalSocketTest::testConnectRefusedNB()
{
	SocketAddress sas("/tmp/poco.server.tcp.sock");
	ServerSocket serv;
	serv.bind(sas);
	serv.listen();
	serv.close();
	StreamSocket ss;
	Timespan timeout(10000);
	SocketAddress sac("/tmp/poco.client.tcp.sock");
	try
	{
		ss.connect(sas, timeout, &sac);
		fail("connection refused - must throw");
	}
	catch (TimeoutException&)
	{
	}
	catch (ConnectionRefusedException&)
	{
	}
}
コード例 #7
0
ファイル: hermes.cpp プロジェクト: jjguti/hermes
int
#ifdef WIN32_SERVICE
hermes_main
#else
main
#endif //WIN32_SERVICE
(int argc,char *argv[])
{
  /* TODO:think of this again
  if(argc>2)
  {
    for(unsigned i=1;i<argc;i++)
    {
      argv++
  }
  */

  #ifdef HAVE_SSL
    CRYPTO_set_locking_callback(ssl_locking_function);
    #ifndef WIN32 //getpid() returns different values for threads on windows, therefor this is not needed
    CRYPTO_set_id_callback(pthread_self);
    #endif //WIN32
  #endif //HAVE_SSL
  try
  {
    if(2==argc)
    {
      if(!Utils::file_exists(argv[1]))
        throw Exception(string(_("Config file "))+argv[1]+_(" doesn't exist or is not readable."),__FILE__,__LINE__);
      cfg.parse(argv[1]);
    }
    else
      throw Exception(_("Config file not specified"), __FILE__, __LINE__);
    cfg.validateConfig();
  }
  catch(Exception &e)
  {
    LERR(e);
    return -1;
  }

  unsigned long nconns=0;

  signal(SIGTERM,exit_requested);
  signal(SIGINT,exit_requested);
  #ifndef WIN32
  signal(SIGCHLD,SIG_IGN);
  signal(SIGPIPE,SIG_IGN);
  #endif //WIN32

  //we have to create the server socket BEFORE chrooting, because if we don't,
  //SSL cannot initialize because it's missing libz
  ServerSocket server;
  pthread_t cleaner_thread;
  string peer_address;

  #ifndef WIN32
    if(cfg.getBackground())
    {
      int retval;

      retval=fork();
      if(retval>0)
        exit(0); //succesful fork

      if(retval<0)
      {
        LERR(_("Error forking into the background") + Utils::errnotostrerror(errno));
        return -1;
      }
    }
    
    if(cfg.getPidFile()!="")
    {
      try
      {
        Utils::write_pid(cfg.getPidFile(),getpid());
      }
      catch(Exception &e)
      {
        LERR(e);
      }
    }

    if(cfg.getChroot()!="")
    {
      //this is needed to get hermes to load the dns resolver BEFORE chrooting
      (void)gethostbyname("hermes-project.com");
      if(-1 == chdir(cfg.getChroot().c_str()))
      {
        LERR(_("Couldn't chdir into ") + cfg.getChroot() + " " + Utils::errnotostrerror(errno) );
        return -1;
      }
      if(-1==chroot(cfg.getChroot().c_str()))
      {
        LERR(_("Couldn't chroot ") + Utils::errnotostrerror(errno));
        return -1;
      }
      if(-1 == chdir("/"))
      {
        LERR(_("Couldn't chdir into /, this shouldn't happen: " + Utils::errnotostrerror(errno)) );
        return -1;
      }
    }
  #endif //WIN32

  LINF("Starting hermes with pid "+Utils::inttostr(getpid()));
  try
  {
    server.init();
    server.setPort(cfg.getListeningPort());
    server.listen(cfg.getListeningPort(),cfg.getBindTo());
  }
  catch(Exception &e)
  {
    LERR(e);
    return -1; //couldn't bind, exit
  }

  #ifndef WIN32
  if(cfg.getDropPrivileges())
  {
    //drop privileges once we have opened the listening port
    if(-1 == setgroups(0,NULL))
    {
      LERR(_("Error dropping priviledges " + Utils::errnotostrerror(errno)) );
      return -1;
    }
    if(-1 == setgid(cfg.getGid()))
    {
      LERR(_("Error setting gid " + Utils::inttostr(cfg.getGid()) + " " + Utils::errnotostrerror(errno)) );
      return -1;
    }
    if(-1 == setuid(cfg.getUid()))
    {
      LERR(_("Error setting uid " + Utils::inttostr(cfg.getUid()) + " " + Utils::errnotostrerror(errno)) );
      return -1;
    }
    if(-1 == setuid(cfg.getUid()))
    {
      LERR(_("Error setting uid " + Utils::inttostr(cfg.getUid()) + " " + Utils::errnotostrerror(errno)) );
      return -1;
    }
  }
  #endif //WIN32

  /* start our cleaner thread */
  if(cfg.getCleanDb())
    pthread_create(&cleaner_thread,NULL,cleaner_thread_run,NULL);

  new_conn_info info;
  stack<new_conn_info> info_stack;
  while(!quit)
  {
    if(server.canRead(1)) //wait one second for incoming connections, if none then loop again(allows us to check for SIGTERM and SIGINT)
    {
      pthread_t thread;
      pthread_attr_t thread_attr;
      pthread_attr_init(&thread_attr);
      pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);

      int retval;
      int fd=server.accept(&peer_address);
      info.new_fd=fd;
      info.peer_address=peer_address;
      info.connection_id=++nconns;
      pthread_mutex_lock(&info_stack_mutex);
      info_stack.push(info);
      pthread_mutex_unlock(&info_stack_mutex);
      retval=pthread_create(&thread,&thread_attr,thread_main,(void *)&info_stack);
      if(retval)
      {
        LERR(_("Error creating thread: ") + Utils::errnotostrerror(retval) + _(". Sleeping 5 seconds before continuing..."));
        sleep(5);
      }
      else
      {
        #ifdef WIN32
        LDEB("New thread created [" + Utils::ulongtostr(nconns) + "] thread_id: " + Utils::ulongtostr((unsigned long)thread.p) + ":" + Utils::ulongtostr(thread.x));
        #else
        LDEB("New thread created [" + Utils::ulongtostr(nconns) + "] thread_id: " + Utils::ulongtostr(thread));
        #endif //WIN32
        pthread_mutex_lock(&childrenlist_mutex);
        children.push_back(nconns);
        pthread_mutex_unlock(&childrenlist_mutex);
      }
    }
  }

  //close connection so that the port is no longer usable
  server.close();

  // wait for all threads to finish
  LINF("Waiting for threads to finish");
  #ifndef WIN32
  while(children.size())
  {
    if(false==cfg.getBackground())
    {
      cout << "Threads active:" << children.size() << (char)13;
      fflush(stdout);
    }
    sleep(1);
  }
  #endif //WIN32
  if(cfg.getCleanDb())
    pthread_join(cleaner_thread,NULL);

  #ifndef WIN32
  if(false==cfg.getBackground())
    cout << endl;
  #endif //WIN32

  #ifdef HAVE_SPF
  Spf::deinitialize();
  #endif //HAVE_SPF
  return 0;
}