* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
+ * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
#include "socket.h"
#include "inspircd.h"
#include "inspircd_io.h"
-#include "inspircd_util.h"
#include "inspstring.h"
#include "helperfuncs.h"
+#include "socketengine.h"
-extern FILE *log_file;
-extern int boundPortCount;
-extern int openSockfd[MAXSOCKS];
+
+extern InspIRCd* ServerInstance;
extern time_t TIME;
-extern bool unlimitcore;
-extern int MaxConn;
+
+InspSocket* socket_ref[MAX_DESCRIPTORS];
InspSocket::InspSocket()
{
this->state = I_DISCONNECTED;
}
-InspSocket::InspSocket(int newfd)
+InspSocket::InspSocket(int newfd, char* ip)
{
this->fd = newfd;
this->state = I_CONNECTED;
+ this->IP = ip;
+ ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE);
+ socket_ref[this->fd] = this;
}
InspSocket::InspSocket(std::string host, int port, bool listening, unsigned long maxtime)
else
{
this->state = I_LISTENING;
+ ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE);
+ socket_ref[this->fd] = this;
log(DEBUG,"New socket now in I_LISTENING state");
return;
}
ip = inet_ntoa(*ia);
}
+ this->IP = ip;
+
timeout_end = time(NULL)+maxtime;
timeout = false;
if ((this->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
}
}
this->state = I_CONNECTING;
+ ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE);
+ socket_ref[this->fd] = this;
return;
}
}
this->OnClose();
shutdown(this->fd,2);
close(this->fd);
+ socket_ref[this->fd] = NULL;
this->fd = -1;
}
}
+std::string InspSocket::GetIP()
+{
+ return this->IP;
+}
+
char* InspSocket::Read()
{
int n = recv(this->fd,this->ibuf,sizeof(this->ibuf),0);
if (n > 0)
{
+ ibuf[n] = 0;
return ibuf;
}
else
{
- log(DEBUG,"EOF or error on socket");
- return NULL;
+ if (n == EAGAIN)
+ {
+ return "";
+ }
+ else
+ {
+ log(DEBUG,"EOF or error on socket");
+ return NULL;
+ }
}
}
// and should be aborted.
int InspSocket::Write(std::string data)
{
- char* d = (char*)data.c_str();
- unsigned int written = 0;
- int n = 0;
- int s = data.length();
- while ((written < data.length()) && (n >= 0))
+ this->Buffer = this->Buffer + data;
+ this->FlushWriteBuffer();
+ return data.length();
+}
+
+void InspSocket::FlushWriteBuffer()
+{
+ int result = 0;
+ if (this->Buffer.length())
{
- n = send(this->fd,d,s,0);
- if (n > 0)
+ result = send(this->fd,this->Buffer.c_str(),this->Buffer.length(),0);
+ if (result > 0)
{
- // If we didnt write everything, advance
- // the pointers so that when we retry
- // the next time around the loop, we try
- // to write what we failed to write before.
- written += n;
- s -= n;
- d += n;
+ /* If we wrote some, advance the buffer forwards */
+ char* n = (char*)this->Buffer.c_str();
+ n += result;
+ this->Buffer = n;
}
}
- return written;
}
-bool InspSocket::Poll()
+bool InspSocket::Timeout(time_t current)
{
- if ((time(NULL) > timeout_end) && (this->state == I_CONNECTING))
+ if ((this->state == I_CONNECTING) && (current > timeout_end))
{
// for non-listening sockets, the timeout can occur
// which causes termination of the connection after
// connection.
this->OnTimeout();
this->OnError(I_ERR_TIMEOUT);
- timeout = true;
+ timeout = true;
this->state = I_ERROR;
- return false;
+ return true;
}
- polls.fd = this->fd;
- state == I_CONNECTING ? polls.events = POLLOUT : polls.events = POLLIN;
- int ret = poll(&polls,1,1);
+ if (this->Buffer.length())
+ this->FlushWriteBuffer();
+ return false;
+}
- if (ret > 0)
+bool InspSocket::Poll()
+{
+ int incoming = -1;
+
+ switch (this->state)
{
- int incoming = -1;
-
- switch (this->state)
- {
- case I_CONNECTING:
- this->SetState(I_CONNECTED);
- return this->OnConnected();
- break;
- case I_LISTENING:
- length = sizeof (client);
- incoming = accept (this->fd, (sockaddr*)&client,&length);
- this->OnIncomingConnection(incoming,inet_ntoa(client.sin_addr));
- return true;
- break;
- case I_CONNECTED:
- return this->OnDataReady();
- break;
- default:
- break;
- }
+ case I_CONNECTING:
+ this->SetState(I_CONNECTED);
+ /* Our socket was in write-state, so delete it and re-add it
+ * in read-state.
+ */
+ ServerInstance->SE->DelFd(this->fd);
+ ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE);
+ return this->OnConnected();
+ break;
+ case I_LISTENING:
+ length = sizeof (client);
+ incoming = accept (this->fd, (sockaddr*)&client,&length);
+ this->OnIncomingConnection(incoming,inet_ntoa(client.sin_addr));
+ return true;
+ break;
+ case I_CONNECTED:
+ return this->OnDataReady();
+ break;
+ default:
+ break;
}
+
+ if (this->Buffer.length())
+ this->FlushWriteBuffer();
+
return true;
}
this->state = s;
}
+InspSocketState InspSocket::GetState()
+{
+ return this->state;
+}
+
+int InspSocket::GetFd()
+{
+ return this->fd;
+}
+
bool InspSocket::OnConnected() { return true; }
void InspSocket::OnError(InspSocketError e) { return; }
int InspSocket::OnDisconnect() { return 0; }
this->Close();
}
-/*
-int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
-int OpenTCPSocket (void)
-*/