/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
- * Copyright (C) 2007-2009 Robin Burchell <robin+git@viroteck.net>
- * Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
- * Copyright (C) 2006-2007 Craig Edwards <craigedwards@brainbox.cc>
+ * Copyright (C) 2020 Matt Schatz <genius3000@g3k.solutions>
+ * Copyright (C) 2019 linuxdaemon <linuxdaemon.irc@gmail.com>
+ * Copyright (C) 2018 Dylan Frank <b00mx0r@aureus.pw>
+ * Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2013, 2017-2020 Sadie Powell <sadie@witchery.services>
+ * Copyright (C) 2013 Adam <Adam@anope.org>
+ * Copyright (C) 2012 Robby <robby@chatbelgie.be>
+ * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ * Copyright (C) 2007 John Brooks <special@inspircd.org>
* Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
- * Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
+ * Copyright (C) 2007 Craig Edwards <brain@inspircd.org>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
Timeout = NULL;
this->fd = newfd;
this->state = I_CONNECTED;
- if (fd > -1)
+ if (HasFd())
SocketEngine::AddFd(this, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE);
}
-void BufferedSocket::DoConnect(const std::string& ipaddr, int aport, unsigned int maxtime, const std::string& connectbindip)
+void BufferedSocket::DoConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int maxtime)
{
- BufferedSocketError err = BeginConnect(ipaddr, aport, maxtime, connectbindip);
+ BufferedSocketError err = BeginConnect(dest, bind, maxtime);
if (err != I_ERR_NONE)
{
state = I_ERROR;
}
}
-BufferedSocketError BufferedSocket::BeginConnect(const std::string& ipaddr, int aport, unsigned int maxtime, const std::string& connectbindip)
-{
- irc::sockets::sockaddrs addr, bind;
- if (!irc::sockets::aptosa(ipaddr, aport, addr))
- {
- ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "BUG: Hostname passed to BufferedSocket, rather than an IP address!");
- return I_ERR_CONNECT;
- }
-
- bind.sa.sa_family = 0;
- if (!connectbindip.empty())
- {
- if (!irc::sockets::aptosa(connectbindip, 0, bind))
- {
- return I_ERR_BIND;
- }
- }
-
- return BeginConnect(addr, bind, maxtime);
-}
-
BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned int timeout)
{
- if (fd < 0)
+ if (!HasFd())
fd = socket(dest.family(), SOCK_STREAM, 0);
- if (fd < 0)
+ if (!HasFd())
return I_ERR_SOCKET;
if (bind.family() != 0)
void StreamSocket::Close()
{
- if (this->fd > -1)
+ if (closing)
+ return;
+
+ closing = true;
+ if (HasFd())
{
// final chance, dump as much of the sendq as we can
DoWrite();
}
}
+void StreamSocket::Close(bool writeblock)
+{
+ if (getSendQSize() != 0 && writeblock)
+ closeonempty = true;
+ else
+ Close();
+}
+
CullResult StreamSocket::cull()
{
Close();
void StreamSocket::DoWrite()
{
if (getSendQSize() == 0)
+ {
+ if (closeonempty)
+ Close();
+
return;
- if (!error.empty() || fd < 0)
+ }
+ if (!error.empty() || !HasFd())
{
ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "DoWrite on errored or closed socket");
return;
if (psendq)
FlushSendQ(*psendq);
+
+ if (getSendQSize() == 0 && closeonempty)
+ Close();
}
void StreamSocket::FlushSendQ(SendQueue& sq)
}
}
+bool StreamSocket::OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc::sockets::sockaddrs& remote)
+{
+ return false;
+}
+
void StreamSocket::WriteData(const std::string &data)
{
- if (fd < 0)
+ if (!HasFd())
{
ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Attempt to write data to dead socket: %s",
data.c_str());
return NULL;
}
+IOHook* StreamSocket::GetLastHook() const
+{
+ IOHook* curr = GetIOHook();
+ IOHook* last = curr;
+
+ for (; curr; curr = GetNextHook(curr))
+ last = curr;
+
+ return last;
+}
+
+
void StreamSocket::AddIOHook(IOHook* newhook)
{
IOHook* curr = GetIOHook();
}
return ret;
}
+
+void StreamSocket::SwapInternals(StreamSocket& other)
+{
+ if (type != other.type)
+ return;
+
+ EventHandler::SwapInternals(other);
+ std::swap(closeonempty, other.closeonempty);
+ std::swap(closing, other.closing);
+ std::swap(error, other.error);
+ std::swap(iohook, other.iohook);
+ std::swap(recvq, other.recvq);
+ std::swap(sendq, other.sendq);
+}