]> git.stg.codes - stg.git/blobdiff - projects/sgauthstress/proto.cpp
Better handling of errors from server. Refactoring.
[stg.git] / projects / sgauthstress / proto.cpp
index dd4984caca545bf5d0243aefa067fab8f8ea47ad..692c6946de9e27bba00295248def0ec364191ff4 100644 (file)
@@ -1,6 +1,10 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <netdb.h>
 #include <arpa/inet.h>
 
+#include <csignal>
 #include <cerrno>
 #include <cstring>
 #include <cassert>
@@ -77,6 +81,10 @@ pthread_mutex_destroy(&mutex);
 
 void * PROTO::Runner(void * data)
 {
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
 PROTO * protoPtr = static_cast<PROTO *>(data);
 protoPtr->Run();
 return NULL;
@@ -172,7 +180,11 @@ void PROTO::Run()
 {
 while (running)
     {
-    int res = poll(&pollFds.front(), pollFds.size(), timeout);
+    int res;
+        {
+        STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+        res = poll(&pollFds.front(), pollFds.size(), timeout);
+        }
     if (res < 0)
         break;
     if (!running)
@@ -182,11 +194,37 @@ while (running)
         printfd(__FILE__, "PROTO::Run() - events: %d\n", res);
         RecvPacket();
         }
+    else
+        {
+        CheckTimeouts();
+        }
     }
 
 stopped = true;
 }
 
+void PROTO::CheckTimeouts()
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+std::list<std::pair<uint32_t, USER> >::iterator it;
+for (it = users.begin(); it != users.end(); ++it)
+    {
+    int delta = difftime(time(NULL), it->second.GetPhaseChangeTime());
+    if ((it->second.GetPhase() == 3) &&
+        (delta > it->second.GetUserTimeout()))
+        {
+        printfd(__FILE__, "PROTO::CheckTimeouts() - user alive timeout (ip: %s, login: '%s', delta: %d > %d)\n", inet_ntostring(it->second.GetIP()).c_str(), it->second.GetLogin().c_str(), delta, it->second.GetUserTimeout());
+        it->second.SetPhase(1);
+        }
+    if ((it->second.GetPhase() == 2) &&
+        (delta > it->second.GetAliveTimeout()))
+        {
+        printfd(__FILE__, "PROTO::CheckTimeouts() - user connect timeout (ip: %s, login: '%s', delta: %d > %d)\n", inet_ntostring(it->second.GetIP()).c_str(), it->second.GetLogin().c_str(), delta, it->second.GetAliveTimeout());
+        it->second.SetPhase(1);
+        }
+    }
+}
+
 bool PROTO::RecvPacket()
 {
 bool result = true;
@@ -198,7 +236,6 @@ for (it = pollFds.begin(), userIt = users.begin(); it != pollFds.end() && userIt
     if (it->revents)
         {
         it->revents = 0;
-        printfd(__FILE__, "PROTO::RecvPacket() - pollfd: %d, socket: %d\n", it->fd, userIt->second.GetSocket());
         assert(it->fd == userIt->second.GetSocket() && "File descriptors from poll fds and users must be syncked");
         struct sockaddr_in addr;
         socklen_t fromLen = sizeof(addr);
@@ -260,6 +297,7 @@ if (user->GetPhase() != 2)
     {
     errorStr = "Unexpected CONN_SYN_ACK";
     printfd(__FILE__, "PROTO::CONN_SYN_ACK_Proc() - wrong phase: %d\n", user->GetPhase());
+    return false;
     }
 
 user->SetPhase(3);
@@ -288,6 +326,7 @@ if (user->GetPhase() != 3)
     {
     errorStr = "Unexpected ALIVE_SYN";
     printfd(__FILE__, "PROTO::ALIVE_SYN_Proc() - wrong phase: %d\n", user->GetPhase());
+    return false;
     }
 
 user->SetPhase(3);
@@ -312,6 +351,7 @@ if (user->GetPhase() != 4)
     {
     errorStr = "Unexpected DISCONN_SYN_ACK";
     printfd(__FILE__, "PROTO::DISCONN_SYN_ACK_Proc() - wrong phase: %d\n", user->GetPhase());
+    return false;
     }
 
 if (user->GetRnd() + 1 != rnd)
@@ -334,6 +374,7 @@ if (user->GetPhase() != 5)
     {
     errorStr = "Unexpected FIN";
     printfd(__FILE__, "PROTO::FIN_Proc() - wrong phase: %d\n", user->GetPhase());
+    return false;
     }
 
 user->SetPhase(1);