File indexing completed on 2025-01-05 04:37:19

0001 /*
0002     SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "serversocket.h"
0008 
0009 #include "socket.h"
0010 #include <QSocketNotifier>
0011 #include <util/log.h>
0012 
0013 using namespace bt;
0014 
0015 namespace net
0016 {
0017 class ServerSocket::Private
0018 {
0019 public:
0020     Private(ConnectionHandler *chandler)
0021         : sock(nullptr)
0022         , rsn(nullptr)
0023         , wsn(nullptr)
0024         , chandler(chandler)
0025         , dhandler(nullptr)
0026     {
0027     }
0028 
0029     Private(DataHandler *dhandler)
0030         : sock(nullptr)
0031         , rsn(nullptr)
0032         , wsn(nullptr)
0033         , chandler(nullptr)
0034         , dhandler(dhandler)
0035         , pool(new BufferPool())
0036     {
0037         pool->setWeakPointer(pool.toWeakRef());
0038     }
0039 
0040     ~Private()
0041     {
0042         delete rsn;
0043         delete wsn;
0044         delete sock;
0045     }
0046 
0047     void reset()
0048     {
0049         delete rsn;
0050         rsn = nullptr;
0051         delete wsn;
0052         wsn = nullptr;
0053         delete sock;
0054         sock = nullptr;
0055     }
0056 
0057     bool isTCP() const
0058     {
0059         return chandler != nullptr;
0060     }
0061 
0062     net::Socket *sock;
0063     QSocketNotifier *rsn;
0064     QSocketNotifier *wsn;
0065     ConnectionHandler *chandler;
0066     DataHandler *dhandler;
0067     bt::BufferPool::Ptr pool;
0068 };
0069 
0070 ServerSocket::ServerSocket(ConnectionHandler *chandler)
0071     : d(new Private(chandler))
0072 {
0073 }
0074 
0075 ServerSocket::ServerSocket(ServerSocket::DataHandler *dhandler)
0076     : d(new Private(dhandler))
0077 {
0078 }
0079 
0080 ServerSocket::~ServerSocket()
0081 {
0082     delete d;
0083 }
0084 
0085 bool ServerSocket::bind(const QString &ip, bt::Uint16 port)
0086 {
0087     return bind(net::Address(ip, port));
0088 }
0089 
0090 bool ServerSocket::bind(const net::Address &addr)
0091 {
0092     d->reset();
0093 
0094     d->sock = new net::Socket(d->isTCP(), addr.protocol() == QAbstractSocket::IPv4Protocol ? 4 : 6);
0095     if (d->sock->bind(addr, d->isTCP())) {
0096         Out(SYS_GEN | LOG_NOTICE) << "Bound to " << addr.toString() << endl;
0097         d->sock->setBlocking(false);
0098         d->rsn = new QSocketNotifier(d->sock->fd(), QSocketNotifier::Read, this);
0099         if (d->isTCP()) {
0100             connect(d->rsn, &QSocketNotifier::activated, this, &ServerSocket::readyToAccept);
0101         } else {
0102             d->wsn = new QSocketNotifier(d->sock->fd(), QSocketNotifier::Write, this);
0103             d->wsn->setEnabled(false);
0104             connect(d->rsn, &QSocketNotifier::activated, this, &ServerSocket::readyToRead);
0105             connect(d->wsn, &QSocketNotifier::activated, this, &ServerSocket::readyToWrite);
0106         }
0107         return true;
0108     } else
0109         d->reset();
0110 
0111     return false;
0112 }
0113 
0114 void ServerSocket::readyToAccept(int)
0115 {
0116     net::Address addr;
0117     int fd = d->sock->accept(addr);
0118     if (fd >= 0)
0119         d->chandler->newConnection(fd, addr);
0120 }
0121 
0122 void ServerSocket::readyToRead(int)
0123 {
0124     net::Address addr;
0125     bt::Uint32 ba = 0;
0126     bool first = true;
0127     while ((ba = d->sock->bytesAvailable()) > 0 || first) {
0128         // The first packet may be 0 bytes in size
0129         Buffer::Ptr buf = d->pool->get(ba < 1500 ? 1500 : ba);
0130         int bytes_read = d->sock->recvFrom(buf->get(), ba, addr);
0131         if (bytes_read <= (int)ba && ba > 0) {
0132             buf->setSize(bytes_read);
0133             d->dhandler->dataReceived(buf, addr);
0134         }
0135         first = false;
0136     }
0137 }
0138 
0139 void ServerSocket::setWriteNotificationsEnabled(bool on)
0140 {
0141     if (d->wsn && d->wsn->isEnabled() != on)
0142         d->wsn->setEnabled(on);
0143 }
0144 
0145 void ServerSocket::setReadNotificationsEnabled(bool on)
0146 {
0147     if (d->rsn && d->rsn->isEnabled() != on)
0148         d->rsn->setEnabled(on);
0149 }
0150 
0151 void ServerSocket::readyToWrite(int)
0152 {
0153     d->dhandler->readyToWrite(this);
0154 }
0155 
0156 int ServerSocket::sendTo(const QByteArray &data, const net::Address &addr)
0157 {
0158     // Only UDP server socket can send
0159     if (!d->dhandler)
0160         return 0;
0161 
0162     return d->sock->sendTo((const Uint8 *)data.data(), data.size(), addr);
0163 }
0164 
0165 int ServerSocket::sendTo(const bt::Uint8 *buf, int size, const net::Address &addr)
0166 {
0167     // Only UDP server socket can send
0168     if (!d->dhandler)
0169         return 0;
0170 
0171     return d->sock->sendTo(buf, size, addr);
0172 }
0173 
0174 bool ServerSocket::setTOS(unsigned char type_of_service)
0175 {
0176     if (d->sock)
0177         return d->sock->setTOS(type_of_service);
0178     else
0179         return false;
0180 }
0181 
0182 }
0183 
0184 #include "moc_serversocket.cpp"