* ---------------------------------------------------
*/
-#include <string>
-#include <sstream>
-#include <iostream>
-#include <fstream>
-#include <stdexcept>
-#include "inspircd_config.h"
#include "socket.h"
#include "configreader.h"
#include "inspstring.h"
{
this->Instance->Log(DEBUG,"No need to resolve %s",this->host);
strlcpy(this->IP,host,MAXBUF);
- timeout_end = time(NULL) + maxtime;
+ timeout_val = maxtime;
this->DoConnect();
}
}
this->state = I_ERROR;
return false;
}
+
+ this->Timeout = new SocketTimeout(this->GetFd(), this->Instance, this, timeout_val, this->Instance->Time());
+ this->Instance->Timers->AddTimer(this->Timeout);
}
this->state = I_CONNECTING;
if (this->fd > -1)
bool InspSocket::FlushWriteBuffer()
{
+ errno = 0;
if ((this->fd > -1) && (this->state == I_CONNECTED))
{
- if (outbuffer.size())
+ /* If we have multiple lines, try to send them all,
+ * not just the first one -- Brain
+ */
+ while (outbuffer.size() && (errno != EAGAIN))
{
+ /* Send a line */
int result = write(this->fd,outbuffer[0].c_str(),outbuffer[0].length());
if (result > 0)
{
if ((unsigned int)result == outbuffer[0].length())
{
/* The whole block was written (usually a line)
- * Pop the block off the front of the queue
+ * Pop the block off the front of the queue,
+ * dont set errno, because we are clear of errors
+ * and want to try and write the next block too.
*/
outbuffer.pop_front();
}
{
std::string temp = outbuffer[0].substr(result);
outbuffer[0] = temp;
+ /* We didnt get the whole line out. arses.
+ * Try again next time, i guess. Set errno,
+ * because we shouldnt be writing any more now,
+ * until the socketengine says its safe to do so.
+ */
+ errno = EAGAIN;
}
}
else if ((result == -1) && (errno != EAGAIN))
this->Instance->Log(DEBUG,"Write error on socket: %s",strerror(errno));
this->OnError(I_ERR_WRITE);
this->state = I_ERROR;
+ this->Instance->SE->DelFd(this);
+ this->Close();
return true;
}
}
return (fd < 0);
}
-bool InspSocket::Timeout(time_t current)
+void SocketTimeout::Tick(time_t now)
{
- if (this->Instance->SE->GetRef(this->fd) != this)
+ if (ServerInstance->SE->GetRef(this->sfd) != this->sock)
{
- this->Instance->Log(DEBUG,"No FD or socket ref");
- return false;
+ ServerInstance->Log(DEBUG,"Our socket has been deleted before the timeout was reached.");
+ return;
}
- if (this->ClosePending)
+ if (this->sock->state == I_CONNECTING)
{
- this->Instance->Log(DEBUG,"Close is pending");
- return true;
- }
-
- if ((this->state == I_CONNECTING) && (current > timeout_end))
- {
- this->Instance->Log(DEBUG,"Timed out, current=%lu timeout_end=%lu");
+ ServerInstance->Log(DEBUG,"Timed out, current=%lu",now);
// for non-listening sockets, the timeout can occur
// which causes termination of the connection after
// the given number of seconds without a successful
// connection.
- this->OnTimeout();
- this->OnError(I_ERR_TIMEOUT);
- timeout = true;
- this->state = I_ERROR;
- return true;
+ this->sock->OnTimeout();
+ this->sock->OnError(I_ERR_TIMEOUT);
+ this->sock->timeout = true;
+ ServerInstance->SE->DelFd(this->sock);
+ /* NOTE: We must set this AFTER DelFd, as we added
+ * this socket whilst writeable. This means that we
+ * must DELETE the socket whilst writeable too!
+ */
+ this->sock->state = I_ERROR;
+ this->sock->Close();
+ delete this->sock;
+ return;
}
- return this->FlushWriteBuffer();
+ this->sock->FlushWriteBuffer();
}
bool InspSocket::Poll()