X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspsocket.cpp;h=e00429bbafc0a36ab90e349a1751a62f41155b1a;hb=e2b0f3dc9ef4d56c71d7abda13e6139ca092e387;hp=59d9558a4ecd25a83930ff9a2935e853080d39b3;hpb=87b1461e2a4710a38b32186c2582da9fe9bb3804;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 59d9558a4..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,7 +51,7 @@ 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); } @@ -61,10 +68,10 @@ void BufferedSocket::DoConnect(const irc::sockets::sockaddrs& dest, const irc::s 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) @@ -95,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(); @@ -114,6 +125,14 @@ void StreamSocket::Close() } } +void StreamSocket::Close(bool writeblock) +{ + if (getSendQSize() != 0 && writeblock) + closeonempty = true; + else + Close(); +} + CullResult StreamSocket::cull() { Close(); @@ -206,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; @@ -242,6 +266,9 @@ void StreamSocket::DoWrite() if (psendq) FlushSendQ(*psendq); + + if (getSendQSize() == 0 && closeonempty) + Close(); } void StreamSocket::FlushSendQ(SendQueue& sq) @@ -344,7 +371,7 @@ bool StreamSocket::OnSetEndPoint(const irc::sockets::sockaddrs& local, const irc 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()); @@ -485,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(); @@ -521,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); +}