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"