Warning, file /sdk/dferry/transport/ipserver.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002    Copyright (C) 2014 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 #include "ipserver.h"
0025 
0026 #include "connectaddress.h"
0027 #include "ipresolver.h"
0028 
0029 #include "icompletionlistener.h"
0030 #include "ipsocket.h"
0031 
0032 #ifdef __unix__
0033 #include <netinet/in.h>
0034 #include <sys/socket.h>
0035 #include <fcntl.h>
0036 #include <unistd.h>
0037 #endif
0038 #ifdef _WIN32
0039 #include <winsock2.h>
0040 #endif
0041 
0042 #include <cassert>
0043 #include <cstring>
0044 
0045 #include <iostream>
0046 
0047 // TODO implement address family (IPv4 / IPv6) support
0048 IpServer::IpServer(const ConnectAddress &ca)
0049    : m_listenFd(-1)
0050 {
0051     assert(ca.type() == ConnectAddress::Type::Tcp);
0052 
0053     const FileDescriptor fd = socket(AF_INET, SOCK_STREAM, 0);
0054     if (!isValidFileDescriptor(fd)) {
0055         std::cerr << "IpServer contruction failed A.\n";
0056         return;
0057     }
0058 #ifdef __unix__
0059     // don't let forks inherit the file descriptor - just in case
0060     fcntl(fd, F_SETFD, FD_CLOEXEC);
0061 #endif
0062     IpResolver resolver(ca);
0063     bool ok = resolver.resultValid();
0064 
0065     ok = ok && bind(fd, resolver.resolved(), resolver.resolvedLength()) == 0;
0066     ok = ok && (::listen(fd, /* max queued incoming connections */ 64) == 0);
0067 
0068     if (ok) {
0069         m_listenFd = fd;
0070     } else {
0071         std::cerr << "IpServer contruction failed B.\n";
0072 #ifdef _WIN32
0073         closesocket(fd);
0074 #else
0075         ::close(fd);
0076 #endif
0077     }
0078 }
0079 
0080 IpServer::~IpServer()
0081 {
0082     close();
0083 }
0084 
0085 IO::Status IpServer::handleIoReady(IO::RW rw)
0086 {
0087     if (rw != IO::RW::Read) {
0088         assert(false);
0089         return IO::Status::InternalError;
0090     }
0091     FileDescriptor connFd = accept(m_listenFd, nullptr, nullptr);
0092     if (!isValidFileDescriptor(connFd)) {
0093         std::cerr << "\nIpServer::notifyRead(): accept() failed.\n\n";
0094         return IO::Status::RemoteClosed;
0095     }
0096 #ifdef __unix__
0097     fcntl(connFd, F_SETFD, FD_CLOEXEC);
0098 #endif
0099     m_incomingConnections.push_back(new IpSocket(connFd));
0100     if (m_newConnectionListener) {
0101         m_newConnectionListener->handleCompletion(this);
0102     }
0103     return IO::Status::OK;
0104 }
0105 
0106 bool IpServer::isListening() const
0107 {
0108     return isValidFileDescriptor(m_listenFd);
0109 }
0110 
0111 void IpServer::platformClose()
0112 {
0113     if (isValidFileDescriptor(m_listenFd)) {
0114 #ifdef _WIN32
0115         closesocket(m_listenFd);
0116 #else
0117         ::close(m_listenFd);
0118 #endif
0119         m_listenFd = InvalidFileDescriptor;
0120     }
0121 }
0122 
0123 FileDescriptor IpServer::fileDescriptor() const
0124 {
0125     return m_listenFd;
0126 }