X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspsocket.cpp;h=e00429bbafc0a36ab90e349a1751a62f41155b1a;hb=b0f16081ccaef527ed4b5434a7264508cf455f39;hp=42e2640a624ef091d8db0266719c5bf9ea5d9bac;hpb=93fa544b2671b078cf81ac04fbb4b48d5e2d1677;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 42e2640a6..e00429bba 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -1,12 +1,19 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2009 Daniel De Graaf - * Copyright (C) 2007-2009 Robin Burchell - * Copyright (C) 2008 Thomas Stagner - * Copyright (C) 2006-2007 Craig Edwards + * Copyright (C) 2020 Matt Schatz + * Copyright (C) 2019 linuxdaemon + * Copyright (C) 2018 Dylan Frank + * Copyright (C) 2013-2016 Attila Molnar + * Copyright (C) 2013, 2017-2020 Sadie Powell + * Copyright (C) 2013 Adam + * Copyright (C) 2012 Robby + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2007-2008 Robin Burchell + * Copyright (C) 2007 John Brooks * Copyright (C) 2007 Dennis Friis - * Copyright (C) 2006 Oliver Lupton + * Copyright (C) 2006-2007 Craig Edwards + * Copyright (C) 2006 Oliver Lupton * * 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 @@ -44,13 +51,13 @@ BufferedSocket::BufferedSocket(int newfd) 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; @@ -59,36 +66,15 @@ void BufferedSocket::DoConnect(const std::string& ipaddr, int aport, unsigned in } } -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) - fd = socket(dest.sa.sa_family, SOCK_STREAM, 0); + if (!HasFd()) + fd = socket(dest.family(), SOCK_STREAM, 0); - if (fd < 0) + if (!HasFd()) return I_ERR_SOCKET; - if (bind.sa.sa_family != 0) + if (bind.family() != 0) { if (SocketEngine::Bind(fd, bind) < 0) return I_ERR_BIND; @@ -116,7 +102,11 @@ BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs& 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(); @@ -135,6 +125,14 @@ void StreamSocket::Close() } } +void StreamSocket::Close(bool writeblock) +{ + if (getSendQSize() != 0 && writeblock) + closeonempty = true; + else + Close(); +} + CullResult StreamSocket::cull() { Close(); @@ -227,8 +225,13 @@ static const int MYIOV_MAX = IOV_MAX < 128 ? IOV_MAX : 128; 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; @@ -263,6 +266,9 @@ void StreamSocket::DoWrite() if (psendq) FlushSendQ(*psendq); + + if (getSendQSize() == 0 && closeonempty) + Close(); } void StreamSocket::FlushSendQ(SendQueue& sq) @@ -358,9 +364,14 @@ 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()); @@ -501,6 +512,18 @@ IOHook* StreamSocket::GetModHook(Module* mod) const 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(); @@ -537,3 +560,17 @@ size_t StreamSocket::getSendQSize() const } 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); +}