]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/connection.cpp
Updated to keep lowermap const within hashcomp.cpp
[user/henk/code/inspircd.git] / src / connection.cpp
index 8a6557e9d5373cf05a515a117f188d3acdd07ab3..384f626e2f2f59f0cbefa57ec3fa6d9bc5d29897 100644 (file)
@@ -28,6 +28,7 @@
 #include "inspircd.h"
 #include "modules.h"
 #include "inspstring.h"
+#include "helperfuncs.h"
 
 using namespace std;
 
@@ -35,10 +36,42 @@ using namespace std;
 extern std::vector<Module*> modules;
 extern std::vector<ircd_module*> factory;
 
+std::deque<std::string> xsums;
+
 extern int MODCOUNT;
 
 extern time_t TIME;
 
+
+/**
+ * The InspIRCd mesh network is maintained by a tree of objects which reference *themselves*.
+ * Every local server has an array of 32 *serverrecs, known as me[]. Each of these represents
+ * a local listening port, and is not null if the user has opened a listening port on the server.
+ * It is assumed nobody will ever want to open more than 32 listening server ports at any one
+ * time (i mean come on, why would you want more, the ircd works fine with ONE).
+ * Each me[] entry has multiple classes within it of type ircd_connector. These are stored in a vector
+ * and each represents a server linked via this socket. If the connection was created outbound,
+ * the connection is bound to the default ip address by using me[defaultRoute] (defaultRoute being
+ * a global variable which indicates the default server to make connections on). If the connection
+ * was created inbound, it is attached to the port the connection came in on. There may be as many
+ * ircd_connector objects as needed in each me[] entry. Each ircd_connector implements the specifics
+ * of an ircd connection in the mesh, however each ircd may have multiple ircd_connector connections
+ * to it, to maintain the mesh link.
+ */
+
+char* xsumtable = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// creates a random id for a line for detection of duplicate messages
+std::string CreateSum()
+{
+       char sum[9];
+       sum[0] = ':';
+       sum[8] = '\0';
+       for(int q = 1; q < 8; q++)
+               sum[q] = xsumtable[rand()%52];
+       return sum;
+}
+
 connection::connection()
 {
        fd = 0;
@@ -266,6 +299,17 @@ bool connection::BeginLink(char* targethost, int newport, char* password, char*
        return false;
 }
 
+void ircd_connector::SetVersionString(std::string newversion)
+{
+       log(DEBUG,"Set version of %s to %s",this->servername.c_str(),newversion.c_str());
+       this->version = newversion;
+}
+
+std::string ircd_connector::GetVersionString()
+{
+       return this->version;
+}
+
 bool connection::MeshCookie(char* targethost, int newport, unsigned long cookie, char* servername)
 {
        char connect[MAXBUF];
@@ -459,20 +503,46 @@ bool connection::SendPacket(char *message, const char* sendhost)
        }
 }
 
+bool already_have_sum(std::string sum)
+{
+       for (int i = 0; i < xsums.size(); i++)
+       {
+               if (xsums[i] == sum)
+               {
+                       return true;
+               }
+       }
+       if (xsums.size() >= 128)
+       {
+               xsums.pop_front();
+       }
+       xsums.push_back(sum);
+       return false;
+}
+
 // receives a packet from any where there is data waiting, first come, first served
 // fills the message and host values with the host where the data came from.
 
-bool connection::RecvPacket(std::deque<std::string> &messages, char* recvhost)
+bool connection::RecvPacket(std::deque<std::string> &messages, char* recvhost,std::deque<std::string> &sums)
 {
-       char data[4096];
-       memset(data, 0, 4096);
+       char data[65536];
+       memset(data, 0, 65536);
        for (int i = 0; i < this->connectors.size(); i++)
        {
                if (this->connectors[i].GetState() != STATE_DISCONNECTED)
                {
                        // returns false if the packet could not be sent (e.g. target host down)
                        int rcvsize = 0;
-                       rcvsize = recv(this->connectors[i].GetDescriptor(),data,4096,0);
+
+                       // check if theres any data on this socket
+                       // if not, continue onwards to the next.
+                       pollfd polls;
+                       polls.fd = this->connectors[i].GetDescriptor();
+                       polls.events = POLLIN;
+                       int ret = poll(&polls,1,1);
+                       if (ret <= 0) continue;
+
+                       rcvsize = recv(this->connectors[i].GetDescriptor(),data,65000,0);
                        data[rcvsize] = '\0';
                        if (rcvsize == -1)
                        {
@@ -495,9 +565,35 @@ bool connection::RecvPacket(std::deque<std::string> &messages, char* recvhost)
                                                std::string text = this->connectors[i].GetBuffer();
                                                if (text != "")
                                                {
+                                                       if ((text[0] == ':') && (text.find(" ") != std::string::npos))
+                                                       {
+                                                               std::string orig = text;
+                                                               log(DEBUG,"Original: %s",text.c_str());
+                                                               std::string sum = text.substr(1,text.find(" ")-1);
+                                                               text = text.substr(text.find(" ")+1,text.length());
+                                                               std::string possible_token = text.substr(1,text.find(" ")-1);
+                                                               if (possible_token.length() > 1)
+                                                               {
+                                                                       sums.push_back("*");
+                                                                       text = orig;
+                                                                       log(DEBUG,"Non-mesh, non-tokenized string passed up the chain");
+                                                               }
+                                                               else
+                                                               {
+                                                                       log(DEBUG,"Packet sum: '%s'",sum.c_str());
+                                                                       if ((already_have_sum(sum)) && (sum != "*"))
+                                                                       {
+                                                                               // we don't accept dupes
+                                                                               log(DEBUG,"Duplicate packet sum %s from server %s dropped",sum.c_str(),this->connectors[i].GetServerName().c_str());
+                                                                               continue;
+                                                                       }
+                                                                       sums.push_back(sum.c_str());
+                                                               }
+                                                       }
+                                                       else sums.push_back("*");
                                                        messages.push_back(text.c_str());
                                                        strlcpy(recvhost,this->connectors[i].GetServerName().c_str(),160);
-                                                       log(DEBUG,"main: Connection::RecvPacket() %d:%s->%s",pushed++,recvhost,text.c_str()); 
+                                                       log(DEBUG,"Connection::RecvPacket() %d:%s->%s",pushed++,recvhost,text.c_str()); 
                                                }
                                        }
                                        return true;
@@ -509,8 +605,3 @@ bool connection::RecvPacket(std::deque<std::string> &messages, char* recvhost)
        return false;
 }
 
-long connection::GenKey()
-{
-       return (random()*time(NULL));
-}
-