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

0001 /*
0002     SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "utpsocket.h"
0008 #include "connection.h"
0009 #include "utpserver.h"
0010 #include <torrent/globals.h>
0011 
0012 namespace utp
0013 {
0014 UTPSocket::UTPSocket()
0015     : net::SocketDevice(bt::UTP)
0016     , blocking(true)
0017     , polled_for_reading(false)
0018     , polled_for_writing(false)
0019 {
0020 }
0021 
0022 UTPSocket::UTPSocket(Connection::WPtr conn)
0023     : net::SocketDevice(bt::UTP)
0024     , conn(conn)
0025     , blocking(true)
0026     , polled_for_reading(false)
0027     , polled_for_writing(false)
0028 {
0029     Connection::Ptr ptr = conn.toStrongRef();
0030     if (ptr) {
0031         setRemoteAddress(ptr->remoteAddress());
0032         ptr->setBlocking(blocking);
0033         m_state = CONNECTED;
0034     }
0035 }
0036 
0037 UTPSocket::~UTPSocket()
0038 {
0039     close();
0040     reset();
0041 }
0042 
0043 bt::Uint32 UTPSocket::bytesAvailable() const
0044 {
0045     Connection::Ptr ptr = conn.toStrongRef();
0046     if (ptr)
0047         return ptr->bytesAvailable();
0048     else
0049         return 0;
0050 }
0051 
0052 void UTPSocket::close()
0053 {
0054     Connection::Ptr ptr = conn.toStrongRef();
0055     if (ptr) {
0056         try {
0057             ptr->close();
0058         } catch (Connection::TransmissionError) {
0059             reset();
0060         }
0061     }
0062 }
0063 
0064 bool UTPSocket::connectSuccesFull()
0065 {
0066     Connection::Ptr ptr = conn.toStrongRef();
0067     if (ptr && ptr->connectionState() == CS_CONNECTED) {
0068         setRemoteAddress(ptr->remoteAddress());
0069         m_state = CONNECTED;
0070         return true;
0071     } else
0072         return false;
0073 }
0074 
0075 bool UTPSocket::connectTo(const net::Address &addr)
0076 {
0077     if (!bt::Globals::instance().isUTPEnabled())
0078         return false;
0079 
0080     UTPServer &srv = bt::Globals::instance().getUTPServer();
0081     reset();
0082 
0083     conn = srv.connectTo(addr);
0084     Connection::Ptr ptr = conn.toStrongRef();
0085     if (!ptr)
0086         return false;
0087 
0088     m_state = CONNECTING;
0089     ptr->setBlocking(blocking);
0090     if (blocking) {
0091         bool ret = ptr->waitUntilConnected();
0092         if (ret)
0093             m_state = CONNECTED;
0094 
0095         return ret;
0096     }
0097 
0098     return ptr->connectionState() == CS_CONNECTED;
0099 }
0100 
0101 int UTPSocket::fd() const
0102 {
0103     return -1;
0104 }
0105 
0106 const net::Address &UTPSocket::getPeerName() const
0107 {
0108     Connection::Ptr ptr = conn.toStrongRef();
0109     if (remote_addr_override)
0110         return addr;
0111     else if (ptr)
0112         return ptr->remoteAddress();
0113     else {
0114         static net::Address null;
0115         return null;
0116     }
0117 }
0118 
0119 net::Address UTPSocket::getSockName() const
0120 {
0121     return net::Address();
0122 }
0123 
0124 bool UTPSocket::ok() const
0125 {
0126     Connection::Ptr ptr = conn.toStrongRef();
0127     return ptr && ptr->connectionState() != CS_CLOSED;
0128 }
0129 
0130 int UTPSocket::recv(bt::Uint8 *buf, int max_len)
0131 {
0132     Connection::Ptr ptr = conn.toStrongRef();
0133     if (!ptr || ptr->connectionState() == CS_CLOSED)
0134         return 0;
0135 
0136     try {
0137         if (ptr->bytesAvailable() == 0) {
0138             if (blocking) {
0139                 if (ptr->waitForData())
0140                     return ptr->recv(buf, max_len);
0141                 else
0142                     return 0; // connection should be closed now
0143             } else
0144                 return -1; // No data ready and not blocking so return -1
0145         } else
0146             return ptr->recv(buf, max_len);
0147     } catch (Connection::TransmissionError &err) {
0148         close();
0149         return -1;
0150     }
0151 }
0152 
0153 void UTPSocket::reset()
0154 {
0155     conn.clear();
0156 }
0157 
0158 int UTPSocket::send(const bt::Uint8 *buf, int len)
0159 {
0160     Connection::Ptr ptr = conn.toStrongRef();
0161     if (!ptr)
0162         return -1;
0163 
0164     try {
0165         return ptr->send(buf, len);
0166     } catch (Connection::TransmissionError &err) {
0167         close();
0168         return -1;
0169     }
0170 }
0171 
0172 void UTPSocket::setBlocking(bool on)
0173 {
0174     blocking = on;
0175     Connection::Ptr ptr = conn.toStrongRef();
0176     if (ptr)
0177         ptr->setBlocking(on);
0178 }
0179 
0180 bool UTPSocket::setTOS(unsigned char type_of_service)
0181 {
0182     Q_UNUSED(type_of_service);
0183     return true;
0184 }
0185 
0186 void UTPSocket::prepare(net::Poll *p, net::Poll::Mode mode)
0187 {
0188     Connection::Ptr ptr = conn.toStrongRef();
0189     if (ptr && ptr->connectionState() != CS_CLOSED) {
0190         UTPServer &srv = bt::Globals::instance().getUTPServer();
0191         srv.preparePolling(p, mode, ptr);
0192         if (mode == net::Poll::OUTPUT)
0193             polled_for_writing = true;
0194         else
0195             polled_for_reading = true;
0196     }
0197 }
0198 
0199 bool UTPSocket::ready(const net::Poll *p, net::Poll::Mode mode) const
0200 {
0201     Q_UNUSED(p);
0202     Connection::Ptr ptr = conn.toStrongRef();
0203     if (!ptr)
0204         return false;
0205 
0206     if (mode == net::Poll::OUTPUT) {
0207         if (polled_for_writing) {
0208             polled_for_writing = false;
0209             return ptr->isWriteable();
0210         }
0211     } else {
0212         if (polled_for_reading) {
0213             polled_for_reading = false;
0214             return bytesAvailable() > 0 || ptr->connectionState() == CS_CLOSED;
0215         }
0216     }
0217 
0218     return false;
0219 }
0220 
0221 }