diff --git a/apps/srt-file-transmit.cpp b/apps/srt-file-transmit.cpp index 541113bf8..d1e42c2e2 100644 --- a/apps/srt-file-transmit.cpp +++ b/apps/srt-file-transmit.cpp @@ -1,3 +1,27 @@ +/***************************************************************************** + * SRT - Secure, Reliable, Transport + * Copyright (c) 2017 Haivision Systems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * + *****************************************************************************/ + +/***************************************************************************** +written by + Haivision Systems Inc. + *****************************************************************************/ + #include #include diff --git a/apps/srt-live-transmit.cpp b/apps/srt-live-transmit.cpp index 4e1145d99..96c8a036f 100644 --- a/apps/srt-live-transmit.cpp +++ b/apps/srt-live-transmit.cpp @@ -46,7 +46,8 @@ // option is SRTO_RCVSYN, which makes connect/accept call asynchronous. // Because of that this option is treated special way in this app. // -// See 'srt_options' global variable for a list of all options. +// See 'srt_options' global variable (common/socketoptions.hpp) for a list of +// all options. // MSVS likes to complain about lots of standard C functions being unsafe. #ifdef _MSC_VER @@ -78,7 +79,7 @@ // NOTE: This is without "haisrt/" because it uses an internal path // to the library. Application using the "installed" library should -// use +// use #include #include diff --git a/apps/srt-multiplex.cpp b/apps/srt-multiplex.cpp index 8f2dcfd31..982affa53 100644 --- a/apps/srt-multiplex.cpp +++ b/apps/srt-multiplex.cpp @@ -37,7 +37,7 @@ using namespace std; const size_t DEFAULT_CHUNK = 1316; const logging::LogFA SRT_LOGFA_APP = 10; -logging::Logger applog(SRT_LOGFA_APP, srt_logger_config, "siplex"); +logging::Logger applog(SRT_LOGFA_APP, srt_logger_config, "srt-mplex"); volatile bool siplex_int_state = false; void OnINT_SetIntState(int) @@ -416,8 +416,8 @@ void Help(string program) "interperted by the application and used to set resource id on an SRT socket when connecting\n" "or to match with the id extracted from the accepted socket of incoming connection.\n" "Example:\n" -"\tSender: siplex srt://remhost:2000 -i udp://:5000?id=low udp://:6000?id=high\n" -"\tReceiver: siplex srt://:2000 -o output-high.ts?id=high output-low.ts?id=low\n" +"\tSender: srt-multiplex srt://remhost:2000 -i udp://:5000?id=low udp://:6000?id=high\n" +"\tReceiver: srt-multiplex srt://:2000 -o output-high.ts?id=high output-low.ts?id=low\n" "\nHere you create a Sender which will connect to 'remhost' port 2000 using multiple SRT\n" "sockets, all of which will be using the same outgoing port. Here the port is autoselected\n" "by the first socket when connecting, every next one will reuse that port. Alternatively you\n" @@ -425,8 +425,8 @@ void Help(string program) "Then for every input resource a separate connection is made and appropriate resource id\n" "will be set to particular socket assigned to that resource according to the 'id' parameter.\n" "When the listener side (here Receiver) gets the socket accepted, it will have the resource\n" -"id set just as the caller side did, in which case siplex will search for this id among the\n" -"registered resources and match the resource (output here) with this id. If the resource is\n" +"id set just as the caller side did, in which case srt-multiplex will search for this id among\n" +"the registered resources and match the resource (output here) with this id. If the resource is\n" "not found, the connection is closed immediately. This works the same way regardless of which\n" "direction is used by caller or listener\n"; @@ -455,9 +455,6 @@ int main( int argc, char** argv ) } } cleanupobj; - //vector args; - //copy(argv+1, argv+argc, back_inserter(args)); - // Check options vector optargs = { { {"ll", "loglevel"}, OptionScheme::ARG_ONE }, @@ -468,7 +465,7 @@ int main( int argc, char** argv ) // The call syntax is: // - // siplex -o/-i ARGS... + // srt-multiplex -o/-i ARGS... // // SRT URI should contain: // srt://[host]:port?mode=MODE&adapter=ADAPTER&port=PORT&otherparameters... diff --git a/apps/suflip.cpp b/apps/suflip.cpp index c670742c4..99004946f 100644 --- a/apps/suflip.cpp +++ b/apps/suflip.cpp @@ -54,7 +54,7 @@ struct InitializeMe copy(false_names_i, false_names_i+4, inserter(false_names, false_names.begin())); } -} g_moron; +} g_initialize_names; bool verbose = false; volatile bool throw_on_interrupt = false; diff --git a/common/appcommon.hpp b/common/appcommon.hpp index 22db60d08..f59bd7336 100644 --- a/common/appcommon.hpp +++ b/common/appcommon.hpp @@ -93,7 +93,7 @@ static inline int inet_pton(int af, const char * src, void * dst) ZeroMemory(&ss, sizeof(ss)); - // work around stupid non-const API + // work around non-const API strncpy(srcCopy, src, INET6_ADDRSTRLEN + 1); srcCopy[INET6_ADDRSTRLEN] = '\0'; diff --git a/common/netinet_any.h b/common/netinet_any.h index e553a029f..760df8455 100644 --- a/common/netinet_any.h +++ b/common/netinet_any.h @@ -28,8 +28,11 @@ written by #include #include "platform_sys.h" -// This is a smart structure that this moron who has designed BSD sockets -// should have defined in the first place. +// This structure should replace every use of sockaddr and its currently +// used specializations, sockaddr_in and sockaddr_in6. This is to simplify +// the use of the original BSD API that relies on type-violating type casts. +// You can use the instances of sockaddr_any in every place where sockaddr is +// required. struct sockaddr_any { @@ -122,7 +125,6 @@ struct sockaddr_any return memcmp(&c1, &c2, sizeof(c1)) < 0; } }; - }; template<> struct sockaddr_any::TypeMap { typedef sockaddr_in type; }; diff --git a/common/transmitmedia.cpp b/common/transmitmedia.cpp index 1d431b5e3..60bcd7fad 100644 --- a/common/transmitmedia.cpp +++ b/common/transmitmedia.cpp @@ -737,9 +737,9 @@ int SrtTarget::ConfigurePre(SRTSOCKET sock) return result; int yes = 1; - // This is for the HSv4 compatibility, if both parties are HSv5 + // This is for the HSv4 compatibility; if both parties are HSv5 // (min. version 1.2.1), then this setting simply does nothing. - // In HSv4 this setting is obligatory otherwise the SRT handshake + // In HSv4 this setting is obligatory; otherwise the SRT handshake // extension will not be done at all. result = srt_setsockopt(sock, 0, SRTO_SENDER, &yes, sizeof yes); if ( result == -1 ) @@ -1013,8 +1013,8 @@ class UdpCommon attr.erase("adapter"); } - // The "ttl" options is handled separately, it maps to either IP_TTL - // or IP_MULTICAST_TTL, depending on whether the address is sc or mc. + // The "ttl" options is handled separately, it maps to both IP_TTL + // and IP_MULTICAST_TTL so that TTL setting works for both uni- and multicast. if (attr.count("ttl")) { int ttl = stoi(attr.at("ttl")); diff --git a/common/utilities.h b/common/utilities.h index e196b22f7..ca8e98c7f 100644 --- a/common/utilities.h +++ b/common/utilities.h @@ -82,9 +82,24 @@ written by // -------------- UTILITIES ------------------------ // Bit numbering utility. -// Usage: Bits // -// You can use it as a typedef (say, "MASKTYPE") and then use the following members: +// This is something that allows you to turn 32-bit integers into bit fields. +// Although bitfields are part of C++ language, they are not designed to be +// interchanged with 32-bit numbers, and any attempt to doing it (by placing +// inside a union, for example) is nonportable (order of bitfields inside +// same-covering 32-bit integer number is dependent on the endian), so they are +// popularly disregarded as useless. Instead the 32-bit numbers with bits +// individually selected is preferred, with usually manual playing around with +// & and | operators, as well as << and >>. This tool is designed to simplify +// the use of them. This can be used to qualify a range of bits inside a 32-bit +// number to be a separate number, you can "wrap" it by placing the integer +// value in the range of these bits, as well as "unwrap" (extract) it from +// the given place. For your own safety, use one prefix to all constants that +// concern bit ranges intended to be inside the same "bit container". +// +// Usage: typedef Bits MASKTYPE; // MASKTYPE is a name of your choice. +// +// With this defined, you can use the following members: // - MASKTYPE::mask - to get the int32_t value with bimask (used bits set to 1, others to 0) // - MASKTYPE::offset - to get the lowermost bit number, or number of bits to shift // - MASKTYPE::wrap(int value) - to create a bitset where given value is encoded in given bits @@ -495,7 +510,7 @@ class DriftTracer // // IMPORTANT: drift() can be called at any time, just remember // that this value may look different than before only if the - // last update() return true, which need not be important for you. + // last update() returned true, which need not be important for you. // // CASE: CLEAR_ON_UPDATE = true // overdrift() should be read only immediately after update() returned diff --git a/srtcore/api.cpp b/srtcore/api.cpp index 9a320088e..faa3a2fd0 100644 --- a/srtcore/api.cpp +++ b/srtcore/api.cpp @@ -632,12 +632,12 @@ int CUDTUnited::bind(SRTSOCKET u, UDPSOCKET udpsock) int CUDTUnited::listen(const SRTSOCKET u, int backlog) { - if (backlog <= 0 ) + if (backlog <= 0) throw CUDTException(MJ_NOTSUP, MN_INVAL, 0); // Don't search for the socket if it's already -1; // this never is a valid socket. - if ( u == UDT::INVALID_SOCK ) + if (u == UDT::INVALID_SOCK) throw CUDTException(MJ_NOTSUP, MN_SIDINVAL, 0); CUDTSocket* s = locate(u); @@ -675,8 +675,7 @@ int CUDTUnited::listen(const SRTSOCKET u, int backlog) catch (...) { delete s->m_pQueuedSockets; - delete s->m_pAcceptSockets; // XXX If this was exception-interrupted, - // then nothing is allocated! + delete s->m_pAcceptSockets; // XXX Translated std::bad_alloc into CUDTException specifying // memory allocation failure... @@ -725,11 +724,13 @@ SRTSOCKET CUDTUnited::accept(const SRTSOCKET listen, sockaddr* addr, int* addrle } else if (ls->m_pQueuedSockets->size() > 0) { - // XXX Actually this should at best be something like that: + // XXX REFACTORING REQUIRED HERE! + // Actually this should at best be something like that: // set::iterator b = ls->m_pQueuedSockets->begin(); // u = *b; // ls->m_pQueuedSockets->erase(b); - // ls->m_pAcceptSockets.insert(u); + // ls->m_pAcceptSockets->insert(u); + // // It is also questionable why m_pQueuedSockets should be of type 'set'. // There's no quick-searching capabilities of that container used anywhere except // checkBrokenSockets and garbageCollect, which aren't performance-critical, @@ -739,9 +740,10 @@ SRTSOCKET CUDTUnited::accept(const SRTSOCKET listen, sockaddr* addr, int* addrle // the first is taken here, which is actually the socket with lowest // possible descriptor value (as default operator< and ascending sorting // used for std::set where SRTSOCKET=int). + // + // Consider using std::list or std::vector here. u = *(ls->m_pQueuedSockets->begin()); - // why suggest the position - it is std::set! ls->m_pAcceptSockets->insert(ls->m_pAcceptSockets->end(), u); ls->m_pQueuedSockets->erase(ls->m_pQueuedSockets->begin()); accepted = true; @@ -909,14 +911,14 @@ int CUDTUnited::close(const SRTSOCKET u) s->m_TimeStamp = CTimer::getTime(); s->m_pUDT->m_bBroken = true; - // NOTE: (changed by Sektor) + // Change towards original UDT: // Leave all the closing activities for garbageCollect to happen, // however remove the listener from the RcvQueue IMMEDIATELY. - // This is because the listener socket is useless anyway and should - // not be used for anything NEW since now. - - // But there's no reason to destroy the world by occupying the - // listener slot in the RcvQueue. + // Even though garbageCollect would eventually remove the listener + // as well, there would be some time interval between now and the + // moment when it's done, and during this time the application will + // be unable to bind to this port that the about-to-delete listener + // is currently occupying (due to blocked slot in the RcvQueue). LOGC(mglog.Debug, log << s->m_pUDT->CONID() << " CLOSING (removing listener immediately)"); { @@ -948,7 +950,7 @@ int CUDTUnited::close(const SRTSOCKET u) s->m_Status = SRTS_CLOSED; - // a socket will not be immediated removed when it is closed + // a socket will not be immediately removed when it is closed // in order to prevent other methods from accessing invalid address // a timer is started and the socket will be removed after approximately // 1 second @@ -1693,7 +1695,7 @@ void CUDTUnited::updateMux( throw e; } - // XXX Looks stupid. Simplify. Use sockaddr_any. + // XXX Simplify this. Use sockaddr_any. sockaddr* sa = (AF_INET == s->m_pUDT->m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; @@ -1726,7 +1728,8 @@ void CUDTUnited::updateMux( "creating new multiplexer for port %i\n", m.m_iPort); } -// XXX This is actually something completely stupid. +// XXX This functionality needs strong refactoring. +// // This function is going to find a multiplexer for the port contained // in the 'ls' listening socket, by searching through the multiplexer // container. @@ -1738,34 +1741,37 @@ void CUDTUnited::updateMux( // didn't, this function wouldn't even have a chance to be called. // // Why can't then the multiplexer be recorded in the 'ls' listening socket data -// to be accessed immediately, especially when one listener can't bind to more than -// one multiplexer at a time (well, even if it could, there's still no reason why -// this should be extracted by "querying")? +// to be accessed immediately, especially when one listener can't bind to more +// than one multiplexer at a time (well, even if it could, there's still no +// reason why this should be extracted by "querying")? // // Maybe because the multiplexer container is a map, not a list. // Why is this then a map? Because it's addressed by MuxID. Why do we need // mux id? Because we don't have a list... ? // -// But what's the multiplexer ID? It's a socket ID for which it was originally created. +// But what's the multiplexer ID? It's a socket ID for which it was originally +// created. // -// Is this then shared? Yes, only between the listener socket and the accepted sockets, -// or in case of "bound" connecting sockets (by binding you can enforce the port number, -// which can be the same for multiple SRT sockets). +// Is this then shared? Yes, only between the listener socket and the accepted +// sockets, or in case of "bound" connecting sockets (by binding you can +// enforce the port number, which can be the same for multiple SRT sockets). // Not shared in case of unbound connecting socket or rendezvous socket. // -// Ok, in which situation do we need dispatching by mux id? Only when the socket is being -// deleted. How does the deleting procedure know the muxer id? Because it is recorded here -// at the time when it's found, as... the socket ID of the actual listener socket being -// actually the first socket to create the multiplexer, so the multiplexer gets its id. +// Ok, in which situation do we need dispatching by mux id? Only when the +// socket is being deleted. How does the deleting procedure know the muxer id? +// Because it is recorded here at the time when it's found, as... the socket ID +// of the actual listener socket being actually the first socket to create the +// multiplexer, so the multiplexer gets its id. // -// Still, no reasons found why the socket can't contain a list iterator to a multiplexer -// INSTEAD of m_iMuxID. There's no danger in this solutio because the multiplexer is never -// deleted until there's at least one socket using it. +// Still, no reasons found why the socket can't contain a list iterator to a +// multiplexer INSTEAD of m_iMuxID. There's no danger in this solution because +// the multiplexer is never deleted until there's at least one socket using it. // -// The multiplexer may even physically be contained in the CUDTUnited object, just track -// the multiple users of it (the listener and the accepted sockets). When deleting, you -// simply "unsubscribe" yourself from the multiplexer, which will unref it and remove the -// list element by the iterator kept by the socket. +// The multiplexer may even physically be contained in the CUDTUnited object, +// just track the multiple users of it (the listener and the accepted sockets). +// When deleting, you simply "unsubscribe" yourself from the multiplexer, which +// will unref it and remove the list element by the iterator kept by the +// socket. void CUDTUnited::updateListenerMux(CUDTSocket* s, const CUDTSocket* ls) { CGuard cg(m_ControlLock); @@ -3041,8 +3047,6 @@ int getlasterror_errno() // Get error string of a given error code const char* geterror_desc(int code, int err) { - // static CUDTException e; //>>Need something better than static here. - // Yeah, of course. Here you are: CUDTException e (CodeMajor(code/1000), CodeMinor(code%1000), err); return(e.getErrorMessage()); } diff --git a/srtcore/buffer.cpp b/srtcore/buffer.cpp index cd6ea1f2f..a5fcdae05 100644 --- a/srtcore/buffer.cpp +++ b/srtcore/buffer.cpp @@ -1122,8 +1122,7 @@ bool CRcvBuffer::getRcvReadyMsg(ref_t tsbpdtime, ref_t curpkt /* * Return receivable data status (packet timestamp ready to play if TsbPd mode) * Return playtime (tsbpdtime) of 1st packet in queue, ready to play or not -*/ -/* +* * Return data ready to be received (packet timestamp ready to play if TsbPd mode) * Using getRcvDataSize() to know if there is something to read as it was widely * used in the code (core.cpp) is expensive in TsbPD mode, hence this simpler function @@ -1403,7 +1402,7 @@ int CRcvBuffer::setRcvTsbPdMode(uint64_t timebase, uint32_t delay) // // This function is called in the HSREQ reception handler only. m_ullTsbPdTimeBase = timebase; - // XXX Note that this is completely wrong. + // XXX Seems like this may not work correctly. // At least this solution this way won't work with application-supplied // timestamps. For that case the timestamps should be taken exclusively // from the data packets because in case of application-supplied timestamps diff --git a/srtcore/buffer.h b/srtcore/buffer.h index 4b56a2342..294228c03 100644 --- a/srtcore/buffer.h +++ b/srtcore/buffer.h @@ -265,22 +265,22 @@ class CRcvBuffer int getRcvDataSize() const; /// Query how many data was received and acknowledged. - /// @param bytes [out] bytes - /// @param spantime [out] spantime + /// @param [out] bytes bytes + /// @param [out] spantime spantime /// @return size in pkts of acked data. int getRcvDataSize(int &bytes, int &spantime); #if SRT_ENABLE_RCVBUFSZ_MAVG /// Query a 1 sec moving average of how many data was received and acknowledged. - /// @param bytes [out] bytes - /// @param spantime [out] spantime + /// @param [out] bytes bytes + /// @param [out] spantime spantime /// @return size in pkts of acked data. int getRcvAvgDataSize(int &bytes, int &spantime); /// Query how many data of the receive buffer is acknowledged. - /// @param now [in] current time in us. + /// @param [in] now current time in us. /// @return none. void updRcvAvgDataSize(uint64_t now); @@ -313,27 +313,10 @@ class CRcvBuffer int readMsg(char* data, int len, ref_t mctrl); - /// Query how many messages are available now. - /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay - /// @return number of messages available for recvmsg. - - // XXX This seems to be a little bit kind-of dissonance - // between the intended code and the reality. This function - // had to return the number of messages available for processing. - // However it turned out that actually: - // - no one is interested with how many messages are available - // - stating that "none" or "any" suffices for all cases - // - so getRcvMsgNum has more-less always the same definition as below - // Which means that there's no difference between - // (getRcvMsgNum() > 0) and (isRcvDataReady()) expression. - // These functions are now blocked as it doesn't make sense completely. - - // int getRcvMsgNum(uint64_t& tsbpdtime) { return isRcvDataReady(tsbpdtime)? 1 : 0; } - // int getRcvMsgNum() { return isRcvDataReady()? 1 : 0; } - /// Query if data is ready to read (tsbpdtime <= now if TsbPD is active). /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay /// of next packet in recv buffer, ready or not. + /// @param [out] curpktseq Sequence number of the packet if there is one ready to play /// @return true if ready to play, false otherwise (tsbpdtime may be !0 in /// both cases). @@ -355,6 +338,7 @@ class CRcvBuffer /// Add packet timestamp for drift caclculation and compensation /// @param [in] timestamp packet time stamp + /// @param [ref] lock Mutex that should be locked for the operation void addRcvTsbPdDriftSample(uint32_t timestamp, pthread_mutex_t& lock); @@ -365,9 +349,9 @@ class CRcvBuffer /// Get information on the 1st message in queue. // Parameters (of the 1st packet queue, ready to play or not): - /// @param tsbpdtime [out] localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none - /// @param passack [out] true if 1st ready packet is not yet acknowleged - /// @param skipseqno [out] -1 or seq number of 1st unacknowledged pkt ready to play preceeded by missing packets. + /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none + /// @param [out] passack true if 1st ready packet is not yet acknowleged (allowed to be delivered to the app) + /// @param [out] skipseqno -1 or seq number of 1st unacknowledged pkt ready to play preceeded by missing packets. /// @retval true 1st packet ready to play (tsbpdtime <= now). Not yet acknowledged if passack == true /// @retval false IF tsbpdtime = 0: rcv buffer empty; ELSE: /// IF skipseqno != -1, packet ready to play preceeded by missing packets.; @@ -377,7 +361,7 @@ class CRcvBuffer bool getRcvFirstMsg(ref_t tsbpdtime, ref_t passack, ref_t skipseqno, ref_t curpktseq); /// Update the ACK point of the buffer. - /// @param len [in] size of data to be skip & acknowledged. + /// @param [in] len size of data to be skip & acknowledged. void skipData(int len); @@ -385,7 +369,7 @@ class CRcvBuffer private: /// Adjust receive queue to 1st ready to play message (tsbpdtime < now). // Parameters (of the 1st packet queue, ready to play or not): - /// @param tsbpdtime [out] localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none + /// @param [out] tsbpdtime localtime-based (uSec) packet time stamp including buffering delay of 1st packet or 0 if none /// @retval true 1st packet ready to play without discontinuity (no hole) /// @retval false tsbpdtime = 0: no packet ready to play @@ -393,7 +377,7 @@ class CRcvBuffer bool getRcvReadyMsg(ref_t tsbpdtime, ref_t curpktseq); /// Get packet delivery local time base (adjusted for wrap around) - /// @param timestamp [in] packet timestamp (relative to peer StartTime), wrapping around every ~72 min + /// @param [in] timestamp packet timestamp (relative to peer StartTime), wrapping around every ~72 min /// @return local delivery time (usec) uint64_t getTsbPdTimeBase(uint32_t timestamp); @@ -407,7 +391,7 @@ class CRcvBuffer private: /// thread safe bytes counter - /// @param bytes [in] number of bytes added/delete (if negative) to/from rcv buffer. + /// @param [in] bytes number of bytes added/delete (if negative) to/from rcv buffer. // XXX Please document. void countBytes(int pkts, int bytes, bool acked = false); diff --git a/srtcore/channel.cpp b/srtcore/channel.cpp index 3fd5ff689..1bcbedff2 100644 --- a/srtcore/channel.cpp +++ b/srtcore/channel.cpp @@ -482,14 +482,16 @@ EReadStatus CChannel::recvfrom(sockaddr* addr, CPacket& packet) const } #else - // XXX This procedure uses the WSARecvFrom function that just reads + // XXX REFACTORING NEEDED! + // This procedure uses the WSARecvFrom function that just reads // into one buffer. On Windows, the equivalent for recvmsg, WSARecvMsg // uses the equivalent of msghdr - WSAMSG, which has different field // names and also uses the equivalet of iovec - WSABUF, which has different // field names and layout. It is important that this code be translated // to the "proper" solution, however this requires that CPacket::m_PacketVector // also uses the "platform independent" (or, better, platform-suitable) type - // which can be appropriate for the appropriate system function, not just iovec. + // which can be appropriate for the appropriate system function, not just iovec + // (see a specifically provided definition for iovec for windows in packet.h). // // For the time being, the msg_flags variable is defined in both cases // so that it can be checked independently, however it won't have any other @@ -554,21 +556,23 @@ EReadStatus CChannel::recvfrom(sockaddr* addr, CPacket& packet) const goto Return_error; } - // Fix for an issue found at Tenecent. - // By some not well known reason, Linux kernel happens to copy only 20 bytes of - // UDP payload and set the MSG_TRUNC flag, whereas pcap shows that full UDP - // packet arrived at the network device, and the free space in a buffer is - // always the same and >1332 bytes. Nice of it to set this flag, though. + // Fix for an issue with Linux Kernel found during tests at Tencent. // - // In normal conditions, no flags should be set. This shouldn't use any - // other flags, but OTOH this situation also theoretically shouldn't happen - // and it does. As a safe precaution, simply treat any flag set on the - // message as "some problem". + // There was a bug in older Linux Kernel which caused that when the internal + // buffer was depleted during reading from the network, not the whole buffer + // was copied from the packet, EVEN THOUGH THE GIVEN BUFFER WAS OF ENOUGH SIZE. + // It was still very kind of the buggy procedure, though, that at least + // they inform the caller about that this has happened by setting MSG_TRUNC + // flag. // - // As a response for this situation, fake that you received no package. This will be - // then a "fake drop", which will result in reXmission. This isn't even much of a fake - // because the packet is partially lost and this loss is irrecoverable. - + // Normally this flag should be set only if there was too small buffer given + // by the caller, so as this code knows that the size is enough, it never + // predicted this to happen. Just for a case then when you run this on a buggy + // system that suffers of this problem, the fix for this case is left here. + // + // When this happens, then you have at best a fragment of the buffer and it's + // useless anyway. This is solved by dropping the packet and fake that no + // packet was received, so the packet will be then retransmitted. if ( msg_flags != 0 ) { LOGC(mglog.Debug, log << CONID() << "NET ERROR: packet size=" << res diff --git a/srtcore/channel.h b/srtcore/channel.h index b27596a41..1e0f559f3 100644 --- a/srtcore/channel.h +++ b/srtcore/channel.h @@ -83,12 +83,12 @@ class CChannel ~CChannel(); /// Open a UDP channel. - /// @param addr [in] The local address that UDP will use. + /// @param [in] addr The local address that UDP will use. void open(const sockaddr* addr = NULL); /// Open a UDP channel based on an existing UDP socket. - /// @param udpsock [in] UDP socket descriptor. + /// @param [in] udpsock UDP socket descriptor. void attach(UDPSOCKET udpsock); @@ -107,53 +107,53 @@ class CChannel int getRcvBufSize(); /// Set the UDP sending buffer size. - /// @param size [in] expected UDP sending buffer size. + /// @param [in] size expected UDP sending buffer size. void setSndBufSize(int size); /// Set the UDP receiving buffer size. - /// @param size [in] expected UDP receiving buffer size. + /// @param [in] size expected UDP receiving buffer size. void setRcvBufSize(int size); /// Query the socket address that the channel is using. - /// @param addr [out] pointer to store the returned socket address. + /// @param [out] addr pointer to store the returned socket address. void getSockAddr(sockaddr* addr) const; /// Query the peer side socket address that the channel is connect to. - /// @param addr [out] pointer to store the returned socket address. + /// @param [out] addr pointer to store the returned socket address. void getPeerAddr(sockaddr* addr) const; /// Send a packet to the given address. - /// @param addr [in] pointer to the destination address. - /// @param packet [in] reference to a CPacket entity. + /// @param [in] addr pointer to the destination address. + /// @param [in] packet reference to a CPacket entity. /// @return Actual size of data sent. int sendto(const sockaddr* addr, CPacket& packet) const; /// Receive a packet from the channel and record the source address. - /// @param addr [in] pointer to the source address. - /// @param packet [in] reference to a CPacket entity. + /// @param [in] addr pointer to the source address. + /// @param [in] packet reference to a CPacket entity. /// @return Actual size of data received. EReadStatus recvfrom(sockaddr* addr, CPacket& packet) const; #ifdef SRT_ENABLE_IPOPTS /// Set the IP TTL. - /// @param ttl [in] IP Time To Live. + /// @param [in] ttl IP Time To Live. /// @return none. void setIpTTL(int ttl); /// Set the IP Type of Service. - /// @param tos [in] IP Type of Service. + /// @param [in] tos IP Type of Service. void setIpToS(int tos); /// Get the IP TTL. - /// @param ttl [in] IP Time To Live. + /// @param [in] ttl IP Time To Live. /// @return TTL. int getIpTTL() const; diff --git a/srtcore/common.cpp b/srtcore/common.cpp index ca1aed203..3353f3005 100644 --- a/srtcore/common.cpp +++ b/srtcore/common.cpp @@ -306,7 +306,6 @@ void CTimer::sleep() } -// // Automatically lock in constructor CGuard::CGuard(pthread_mutex_t& lock, bool shouldwork): m_Mutex(lock), @@ -875,8 +874,13 @@ void logging::LogDispatcher::CreateLogLinePrefix(std::ostringstream& serr) time_t t = tv.tv_sec; struct tm tm = LocalTime(t); - // Looxlike The %T is nonstandard and Windows - // uses %X here. And "excepts" when using %T. + // Nice to have %T as "standard time format" for logs, + // but it's Single Unix Specification and doesn't exist + // on Windows. Use %X on Windows (it's described as + // current time without date according to locale spec). + // + // XXX Consider using %X everywhere, as it should work + // on both systems. #ifdef WIN32 strftime(tmp_buf, 512, "%X.", &tm); #else diff --git a/srtcore/common.h b/srtcore/common.h index 0658d1439..31a6f80ff 100644 --- a/srtcore/common.h +++ b/srtcore/common.h @@ -104,7 +104,7 @@ enum UDTMessageType // This side's role is: INITIATOR prepares the environment first, and sends // appropriate information to the peer. The peer must be RESPONDER and be ready -// to receive it. It's important for the encryption: the INITIATOR side generates +// to receive it. It's important for the encryption: the INITIATOR side generates // the KM, and sends it to RESPONDER. RESPONDER awaits KM received from the // INITIATOR. Note that in bidirectional mode - that is always with HSv5 - the // INITIATOR creates both sending and receiving contexts, then sends the key to @@ -113,18 +113,19 @@ enum UDTMessageType // // The method of selection: // -// In HSv4, it's always data sender INITIATOR, and receiver - RESPONDER. The HSREQ -// and KMREQ are done AFTER the UDT connection is done using UMSG_EXT extension -// messages. As this is unidirectional, the INITIATOR prepares the sending context -// only, the RESPONDER - receiving context only. +// In HSv4, it's always data sender (the party that sets SRTO_SENDER flag on the +// socket) INITIATOR, and receiver - RESPONDER. The HSREQ and KMREQ are done +// AFTER the UDT connection is done using UMSG_EXT extension messages. As this +// is unidirectional, the INITIATOR prepares the sending context only, the +// RESPONDER - receiving context only. // // In HSv5, for caller-listener configuration, it's simple: caller is INITIATOR, // listener is RESPONDER. In case of rendezvous the parties are equivalent, // so the role is resolved by "cookie contest". Rendezvous sockets both know // each other's cookie generated during the URQ_WAVEAHAND handshake phase. -// The cookies are simply compared as integer numbers; the party that has baked -// a bigger cookie wins, and becomes a INITIATOR. The other loses and becomes an -// RESPONDER. +// The cookies are simply compared as integer numbers; the party which's cookie +// is a greater number becomes an INITIATOR, and the other party becomes a +// RESPONDER. // // The case of a draw - that both occasionally have baked identical cookies - // is treated as an extremely rare and virtually impossible case, so this @@ -144,18 +145,18 @@ std::string MessageTypeStr(UDTMessageType mt, uint32_t extt = 0); // Commonly used by various reading facilities enum EReadStatus { - RST_OK = 0, // A new portion of data has been received - RST_AGAIN, // Nothing has been received, try again - RST_ERROR = -1 // Irrecoverable error, please close descriptor and stop reading. + RST_OK = 0, //< A new portion of data has been received + RST_AGAIN, //< Nothing has been received, try again + RST_ERROR = -1 //< Irrecoverable error, please close descriptor and stop reading. }; enum EConnectStatus { - CONN_ACCEPT = 0, // Received final handshake that confirms connection established - CONN_REJECT = -1, // Error during processing handshake. - CONN_CONTINUE = 1, // induction->conclusion phase - CONN_RENDEZVOUS = 2, // pass to a separate rendezvous processing (HSv5 only) - CONN_AGAIN = -2 // No data was read, don't change any state. + CONN_ACCEPT = 0, //< Received final handshake that confirms connection established + CONN_REJECT = -1, //< Error during processing handshake. + CONN_CONTINUE = 1, //< induction->conclusion phase + CONN_RENDEZVOUS = 2, //< pass to a separate rendezvous processing (HSv5 only) + CONN_AGAIN = -2 //< No data was read, don't change any state. }; std::string ConnectStatusStr(EConnectStatus est); @@ -167,13 +168,13 @@ const int64_t BW_INFINITE = 30000000/8; //Infinite=> 30Mbps enum ETransmissionEvent { TEV_INIT, // --> After creation, and after any parameters were updated. - TEV_ACK, // --> CCC:onAck() + TEV_ACK, // --> When handling UMSG_ACK - older CCC:onAck() TEV_ACKACK, // --> UDT does only RTT sync, can be read from CUDT::RTT(). - TEV_LOSSREPORT, // --> CCC::onLoss() + TEV_LOSSREPORT, // --> When handling UMSG_LOSSREPORT - older CCC::onLoss() TEV_CHECKTIMER, // --> See TEV_CHT_REXMIT - TEV_SEND, // --> CCC::onPktSent - TEV_RECEIVE, // --> CCC::onPktReceived - TEV_CUSTOM, // --> CCC::processCustomMsg, but probably dead call + TEV_SEND, // --> When the packet is scheduled for sending - older CCC::onPktSent + TEV_RECEIVE, // --> When a data packet was received - older CCC::onPktReceived + TEV_CUSTOM, // --> probably dead call - older CCC::processCustomMsg TEV__SIZE }; @@ -311,7 +312,7 @@ class EventArgType; // The 'type' field wouldn't be even necessary if we -// could use any method of extracting 'type' from 'type U::*' expression. + template<> struct EventVariant::VariantFor { typedef CPacket* type; @@ -336,14 +337,16 @@ template<> struct EventVariant::VariantFor static type U::*field() { return &U::init; } }; -// Sigh. The code must be C++03, C++11 and C++17 compliant. -// There's std::mem_fun in C++03, but it's deprecated in C++11 and removed in -// C++17. There's std::function and std::bind, but only since C++11. No way to -// define it any compatible way. There were already problems with ref_t and -// unique_ptr/auto_ptr, for which custom classes were needed. +// Using a hand-crafted solution because there's a non-backward-compatible +// change between C++03 and others on the way up to C++17 (and we want this +// code to be compliant with all C++ standards): +// +// - there's std::mem_fun in C++03 - deprecated in C++11, removed in C++17 +// - std::function in C++11 would be perfect, but not in C++03 // This can be changed in future to use C++11 way, but only after C++03 -// compatibility is finally abaondoned. Until then, this stays with a custom class. +// compatibility is finally abaondoned. Until then, this stays with a custom +// class. class EventSlotBase { @@ -439,12 +442,12 @@ class CTimer public: /// Sleep for "interval" CCs. - /// @param interval [in] CCs to sleep. + /// @param [in] interval CCs to sleep. void sleep(uint64_t interval); /// Seelp until CC "nexttime". - /// @param nexttime [in] next time the caller is waken up. + /// @param [in] nexttime next time the caller is waken up. void sleepto(uint64_t nexttime); @@ -459,7 +462,7 @@ class CTimer public: /// Read the CPU clock cycle into x. - /// @param x [out] to record cpu clock cycles. + /// @param [out] x to record cpu clock cycles. static void rdtsc(uint64_t &x); diff --git a/srtcore/core.cpp b/srtcore/core.cpp index 5fa878652..df6b981bf 100644 --- a/srtcore/core.cpp +++ b/srtcore/core.cpp @@ -317,7 +317,7 @@ CUDT::CUDT(const CUDT& ancestor) m_pCache = ancestor.m_pCache; - // Smoother's copy constructur copies the selection, + // Smoother's copy constructor copies the selection, // but not the underlying smoother object. After // copy-constructed, the 'configure' must be called on it again. m_Smoother = ancestor.m_Smoother; @@ -696,7 +696,7 @@ void CUDT::setOpt(SRT_SOCKOPT optName, const void* optval, int optlen) case SRTT_LIVE: // Default live options: // - tsbpd: on - // - latency: 125ms + // - latency: 120ms // - smoother: live // - extraction method: message (reading call extracts one message) m_bOPT_TsbPd = true; @@ -1608,9 +1608,14 @@ bool CUDT::createSrtHandshake(ref_t r_pkt, ref_t r_hs, if (have_smoother) { // Pass the smoother to the other side as informational. - // The other side should rejeect connection if it uses a different smoother. + // The other side should reject connection if it uses a different smoother. // The other side should also respond with the smoother it uses, if its non-default (for backward compatibility). + // XXX Consider change the smoother settings in the listener socket to "adaptive" + // smoother and also "adaptive" value of CUDT::m_bMessageAPI so that the caller + // may ask for whatever kind of transmission it wants, or select transmission + // type differently for different connections, however with the same listener. + offset += ra_size; pcmdspec = p+offset; ++offset; @@ -2737,12 +2742,12 @@ void CUDT::startConnect(const sockaddr* serv_addr, int32_t forced_isn) // turned into conclusion, but was sending still the original // induction handshake challenge message. It was working only // thanks to that simultaneously there were being sent handshake - // messages from a separate thread (CSndQueue::worker) from - weird - // as it's used in this mode - RendezvousQueue, this time - // serialized properly, which caused that with blocking mode there - // was a kinda initial "drunk passenger with taxi driver talk" - // until the RendezvousQueue sends (when "the time comes") the - // right CONCLUSION handshake challenge. + // messages from a separate thread (CSndQueue::worker) from + // RendezvousQueue, this time serialized properly, which caused + // that with blocking mode there was a kinda initial "drunk + // passenger with taxi driver talk" until the RendezvousQueue sends + // (when "the time comes") the right CONCLUSION handshake + // challenge message. // // Now that this is fixed, the handshake messages from RendezvousQueue // are sent only when there is a rendezvous mode or non-blocking mode. @@ -2810,8 +2815,8 @@ EConnectStatus CUDT::processAsyncConnectResponse(const CPacket& pkt) ATR_NOEXCEP bool CUDT::processAsyncConnectRequest(EConnectStatus cst, const CPacket& response, const sockaddr* serv_addr) { - // Ok, LISTEN UP! - // + // IMPORTANT! + // This function is called, still asynchronously, but in the order // of call just after the call to the above processAsyncConnectResponse. // This should have got the original value returned from @@ -3104,7 +3109,7 @@ EConnectStatus CUDT::processConnectResponse(const CPacket& response, CUDTExcepti // Returned values: // - CONN_REJECT: there was some error when processing the response, connection should be rejected // - CONN_ACCEPT: the handshake is done and finished correctly - // - CONN_CONTINUE: the induction handshake has been processed correctly, it's expected CONCLUSION handshake + // - CONN_CONTINUE: the induction handshake has been processed correctly, and expects CONCLUSION handshake if (!m_bConnecting) return CONN_REJECT; @@ -4653,7 +4658,7 @@ int CUDT::sendmsg2(const char* data, int len, ref_t r_mctrl) // such number of data will be then written out, and this function // will effectively return either -1 (error) or the value of 'len'. // This call will be also rejected from upside when trying to send - // out a message of lengh that exceeds the total size of sending + // out a message of a length that exceeds the total size of the sending // buffer (configurable by SRTO_SNDBUF). if (m_bMessageAPI && len > int(m_iSndBufSize * m_iMaxSRTPayloadSize)) @@ -4731,6 +4736,7 @@ int CUDT::sendmsg2(const char* data, int len, ref_t r_mctrl) throw CUDTException(MJ_PEERERROR); } } + /* * The code below is to return ETIMEOUT when blocking mode could not get free buffer in time. * If no free buffer available in non-blocking mode, we alredy returned. If buffer availaible, @@ -4986,17 +4992,10 @@ int CUDT::receiveMessage(char* data, int len, ref_t r_mctrl) } /* XXX DEBUG STUFF - enable when required - char charbool[2] = {'0', '1'}; - char ptrn [] = "RECVMSG/GO-ON BROKEN 1 CONN 1 CLOSING 1 TMOUT 1 NMSG "; - int pos [] = {21, 28, 38, 46, 53}; - ptrn[pos[0]] = charbool[m_bBroken]; - ptrn[pos[1]] = charbool[m_bConnected]; - ptrn[pos[2]] = charbool[m_bClosing]; - ptrn[pos[3]] = charbool[timeout]; - int wrtlen = sprintf(ptrn + pos[4], "%d", m_pRcvBuffer->getRcvMsgNum()); - strcpy(ptrn + pos[4] + wrtlen, "\n"); - fputs(ptrn, stderr); - // */ + LOGC(dlog.Debug, "RECVMSG/GO-ON BROKEN " << m_bBroken << " CONN " << m_bConnected + << " CLOSING " << m_bClosing << " TMOUT " << timeout + << " NMSG " << m_pRcvBuffer->getRcvMsgNum()); + */ res = m_pRcvBuffer->readMsg(data, len, r_mctrl); @@ -5030,16 +5029,8 @@ int CUDT::receiveMessage(char* data, int len, ref_t r_mctrl) s_UDTUnited.m_EPoll.update_events(m_SocketID, m_sPollID, UDT_EPOLL_IN, false); } - /* XXX DEBUG STUFF - enable when required - { - char ptrn [] = "RECVMSG/EXIT RES ? RCVTIMEOUT "; - char chartribool [3] = { '-', '0', '+' }; - int pos [] = { 17, 29 }; - ptrn[pos[0]] = chartribool[int(res >= 0) + int(res > 0)]; - sprintf(ptrn + pos[1], "%d\n", m_iRcvTimeOut); - fputs(ptrn, stderr); - } - // */ + // Unblock when required + //LOGC(tslog.Debug, "RECVMSG/EXIT RES " << res << " RCVTIMEOUT"); if ((res <= 0) && (m_iRcvTimeOut >= 0)) throw CUDTException(MJ_AGAIN, MN_XMTIMEOUT, 0); @@ -5841,13 +5832,13 @@ void CUDT::sendCtrl(UDTMessageType pkttype, void* lparam, void* rparam, int size else if (ack == m_iRcvLastAck) { // If the ACK was just sent already AND elapsed time did not exceed RTT, - if ((currtime_tk - m_ullLastAckTime_tk) < ((m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency)) + if ((currtime_tk - m_ullLastAckTime_tk) < ((m_iRTT + 4 * m_iRTTVar) * m_ullCPUFrequency)) { CGuard::leaveCS(m_AckLock); break; } } - else + else { // Not possible (m_iRcvCurrSeqNo+1 < m_iRcvLastAck ?) CGuard::leaveCS(m_AckLock); @@ -5863,8 +5854,11 @@ void CUDT::sendCtrl(UDTMessageType pkttype, void* lparam, void* rparam, int size // also known as ACKD_TOTAL_SIZE_VER100. int32_t data[ACKD_TOTAL_SIZE]; - // Pay no attention to this stupidity. CAckNo::incack does exactly - // the same thing as CSeqNo::incseq - and it wouldn't work otherwise. + // Case you care, CAckNo::incack does exactly the same thing as + // CSeqNo::incseq. Logically the ACK number is a different thing + // than sequence number (it's a "journal" for ACK request-response, + // and starts from 0, unlike sequence, which starts from a random + // number), but still the numbers are from exactly the same domain. m_iAckSeqNo = CAckNo::incack(m_iAckSeqNo); data[ACKD_RCVLASTACK] = m_iRcvLastAck; data[ACKD_RTT] = m_iRTT; @@ -6773,9 +6767,7 @@ int CUDT::packData(CPacket& packet, uint64_t& ts_tk) m_ullTraceBytesRetrans += payload; m_ullBytesRetransTotal += payload; - //* - - // Alright, gr8. Despite the contextual interpretation of packet.m_iMsgNo around + // Kinda confusion here. Despite the contextual interpretation of packet.m_iMsgNo around // CSndBuffer::readData version 2 (version 1 doesn't return -1), in this particular // case we can be sure that this is exactly the value of PH_MSGNO as a bitset. // So, set here the rexmit flag if the peer understands it. @@ -6783,7 +6775,6 @@ int CUDT::packData(CPacket& packet, uint64_t& ts_tk) { packet.m_iMsgNo |= PACKET_SND_REXMIT; } - // */ reason = "reXmit"; } else @@ -7703,7 +7694,7 @@ int CUDT::processConnectRequest(const sockaddr* addr, CPacket& packet) LOGF(mglog.Error, "UU:newConnection: rsp(REJECT): %d", URQ_ERROR_REJECT); } - // XXX developer disorder warning! + // CONFUSION WARNING! // // The newConnection() will call acceptAndRespond() if the processing // was successful - IN WHICH CASE THIS PROCEDURE SHOULD DO NOTHING. @@ -7959,7 +7950,8 @@ void CUDT::checkTimers() // XXX Still, if neither FASTREXMIT nor LATEREXMIT part is executed, then // there's no "blind rexmit" done at all. The only other rexmit method // than LOSSREPORT-based is then NAKREPORT (the receiver sends LOSSREPORT - // again after it didn't get a "response" for the previous one). + // again after it didn't get a "response" for the previous one). MIND that + // probably some method of "blind rexmit" MUST BE DONE, when TLPKTDROP is off. && !m_bPeerNakReport && m_pSndBuffer->getCurrBufSize() > 0) { diff --git a/srtcore/logging.h b/srtcore/logging.h index 5d2116eb2..77a3ad7aa 100644 --- a/srtcore/logging.h +++ b/srtcore/logging.h @@ -56,9 +56,19 @@ written by #if ENABLE_LOGGING -// Usage: LOGC(mglog.Debug) << param1 << param2 << param3; +// GENERAL NOTE: All logger functions ADD THEIR OWN \n (EOL). Don't add any your own EOL character. +// The logging system may not add the EOL character, if appropriate flag was set in log settings. +// Anyway, treat the whole contents of eventually formatted message as exactly one line. + +// LOGC uses an iostream-like syntax, using the special 'log' symbol. +// This symbol isn't visible outside the log macro parameters. +// Usage: LOGC(mglog.Debug, log << param1 << param2 << param3); #define LOGC(logdes, args) if (logdes.CheckEnabled()) { logging::LogDispatcher::Proxy log(logdes); log.setloc(__FILE__, __LINE__, __FUNCTION__); args; } + +// LOGF uses printf-like style formatting. +// Usage: LOGF(mglog.Debug, "%s: %d", param1.c_str(), int(param2)); #define LOGF(logdes, ...) if (logdes.CheckEnabled()) logdes().setloc(__FILE__, __LINE__, __FUNCTION__).form(__VA_ARGS__) + // LOGP is C++11 only OR with only one string argument. // Usage: LOGP(mglog.Debug, param1, param2, param3); #define LOGP(logdes, ...) if (logdes.CheckEnabled()) logdes.printloc(__FILE__, __LINE__, __FUNCTION__,##__VA_ARGS__) @@ -165,7 +175,7 @@ struct SRT_API LogDispatcher template void PrintLogLine(const char* file, int line, const std::string& area, const Arg& arg); - // For old C++ standard provide only with one argument. + // For C++03 (older) standard provide only with one argument. template void operator()(const Arg& arg) { diff --git a/srtcore/packet.h b/srtcore/packet.h index 84d7a1e8c..a6f78cfa2 100644 --- a/srtcore/packet.h +++ b/srtcore/packet.h @@ -70,10 +70,14 @@ modified by #ifdef WIN32 -// XXX This is stupid. Instead of providing this, the -// appropriate equivalent system type on Windows should be used. -// Then, instead of `iovec`, some portable definition should be used. -// See the definition of WSARecvMsg for details. +// XXX REFACTOR THIS. + +// Instead of providing this, the appropriate equivalent system type on Windows +// should be used. Then, instead of `iovec`, some portable definition should +// be used. See the definition of WSARecvMsg for details. + +// Note that iovec is part of CPacket definition, so the common type name should +// be used there. Fortunately, the Windows definition differs only by field names. struct iovec { @@ -255,7 +259,7 @@ friend class CRcvQueue; int32_t getAckSeqNo() const; uint16_t getControlFlags() const; - // Note: this will return a stupid value, if the packet + // Note: this will return a "singular" value, if the packet // contains the control message int32_t getSeqNo() const { diff --git a/srtcore/queue.cpp b/srtcore/queue.cpp index c205b99bd..1d22f5f8d 100644 --- a/srtcore/queue.cpp +++ b/srtcore/queue.cpp @@ -1255,8 +1255,8 @@ EConnectStatus CRcvQueue::worker_ProcessConnectionRequest(CUnit* unit, const soc // drop the connection request. The only user process that is connected // to it is accept() call (or connect() in case of rendezvous), but // the system cannot return an error from accept() just because some - // user was attempting to connect, but was too stupid to properly - // formulate the connection request. + // user was attempting to connect, but formulated the connection + // request incorrectly. // The only thing that could be done in case when the "listen" call // fails, is to probably send a short information packet (once; it's