/* Cut cwnd and enter fast recovery mode upon triple dupack */ void TcpNewReno::DupAck (const TcpHeader& t, uint32_t count) { NS_LOG_FUNCTION (this << count); if (count == m_retxThresh && !m_inFastRec) { // triple duplicate ack triggers fast retransmit (RFC2582 sec.3 bullet #1) m_ssThresh = std::max (2 * m_segmentSize, BytesInFlight () / 2); m_cWnd = m_ssThresh + 3 * m_segmentSize; m_recover = m_highTxMark; m_inFastRec = true; NS_LOG_INFO ("Triple dupack. Enter fast recovery mode. Reset cwnd to " << m_cWnd << ", ssthresh to " << m_ssThresh << " at fast recovery seqnum " << m_recover); DoRetransmit (); } else if (m_inFastRec) { // Increase cwnd for every additional dupack (RFC2582, sec.3 bullet #3) m_cWnd += m_segmentSize; NS_LOG_INFO ("Dupack in fast recovery mode. Increase cwnd to " << m_cWnd); SendPendingData (m_connected); } else if (!m_inFastRec && m_limitedTx && m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0) { // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit NS_LOG_INFO ("Limited transmit"); uint32_t sz = SendDataPacket (m_nextTxSequence, m_segmentSize, true); m_nextTxSequence += sz; // Advance next tx sequence }; }
void BluetoothDaemonConnectionIO::OnSocketCanSendWithoutBlocking() { MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); MOZ_ASSERT(!IsShutdownOnIOThread()); if (NS_WARN_IF(NS_FAILED(SendPendingData(GetFd())))) { RemoveWatchers(WRITE_WATCHER); } }
void UnixSocketConsumerIO::OnSocketCanSendWithoutBlocking() { MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 nsresult rv = SendPendingData(GetFd(), this); if (NS_FAILED(rv)) { return; } if (HasPendingData()) { AddWatchers(WRITE_WATCHER, false); } }
void CAdminSocket::OnSend(int nErrorCode) { if (nErrorCode) { Close(); m_pAdminInterface->Remove(this); return; } if( !SendPendingData() ) { Close(); m_pAdminInterface->Remove(this); return; } }
BOOL CAdminSocket::SendCommand(int nType, int nID, const void *pData, int nDataLength) { if (m_bStillNeedAuth) return TRUE; t_data data(nDataLength + 5); *data.pData = nType; *data.pData |= nID << 2; memcpy(&*data.pData + 1, &nDataLength, 4); if (pData) memcpy(&*data.pData + 5, pData, nDataLength); m_SendBuffer.push_back(data); return SendPendingData(); }
BOOL CAdminSocket::SendCommand(LPCTSTR pszCommand, int nTextType) { std::string utf8; if (pszCommand) utf8 = ConvToNetwork(pszCommand); DWORD nDataLength = utf8.size() + 1; t_data data(nDataLength + 5); *data.pData = 2; *data.pData |= 1 << 2; memcpy(&*data.pData + 1, &nDataLength, 4); *(&*data.pData+5) = nTextType; memcpy(reinterpret_cast<char *>(&*data.pData+6), utf8.c_str(), nDataLength - 1); m_SendBuffer.push_back(data); return SendPendingData(); }
void TCPServerListener::Listen() { _RPT0(0, "TCPServer: Starting to Listen\n"); fd_set test_set; fd_set test_set2; timeval t; t.tv_sec = 1; // Shutdown test every second t.tv_usec = 0; timeval t2; // Always nonblock t2.tv_sec = 0; t2.tv_usec = 0; ClientConnection s_list[FD_SETSIZE]; int i; if (lzo_init() != LZO_E_OK) { env->ThrowError("TCPServer: Could not initialize LZO compression library!"); } ServerReply s; for (i = 0; i < FD_SETSIZE ; i++) memset(&s_list[i], 0, sizeof(ClientConnection)); while (!shutdown) { // Attempt to Accept an incoming request FD_ZERO(&test_set); FD_SET(m_socket, &test_set); select(0, &test_set, NULL, NULL, &t2); if (FD_ISSET(m_socket, &test_set)) { AcceptClient(accept( m_socket, NULL, NULL ), &s_list[0]); _RPT0(0, "TCPServer: Client Connected.\n"); } FD_ZERO(&test_set); FD_ZERO(&test_set2); bool anyconnected = false; for (i = 0; i < FD_SETSIZE; i++) { if (s_list[i].isConnected) { FD_SET(s_list[i].s, &test_set); if (s_list[i].isDataPending) { FD_SET(s_list[i].s, &test_set2); } anyconnected = true; } } if (!anyconnected) { Sleep(100); continue; } select(0, &test_set, &test_set2, NULL, &t); bool request_handled = false; for (i = 0; i < FD_SETSIZE; i++) { s.dataSize = 0; if (s_list[i].isConnected) { if (FD_ISSET(s_list[i].s, &test_set) && (!s_list[i].isDataPending)) { request_handled = true; TCPRecievePacket* tr = new TCPRecievePacket(s_list[i].s); _RPT1(0, "TCPServer: Bytes Recv: %ld\n", tr->dataSize ); if (!tr->isDisconnected) { s.dataSize = 0; s.client = &s_list[i]; // Add client info to serverreply. Receive(tr, &s); if (s.dataSize > 0) { SendPacket(&s_list[i], &s); } // end if datasize > 0 } else { // isDisconnected _RPT0(0, "TCPServer: Connection Closed.\n"); closesocket(s_list[i].s); s_list[i].reset(); } delete tr; } // end if fd is set } // end if list != null } // end for i for (i = 0; i < FD_SETSIZE; i++) { if (FD_ISSET(s_list[i].s, &test_set2) && s_list[i].isDataPending ) { request_handled = true; SendPendingData(&s_list[i]); } // end if isDataPending } if (!request_handled) { t.tv_usec = 100000; // If no request we allow it to wait 100 ms instead. if (prefetch_frame > 0) { _RPT1(0, "TCPServer: Prerequesting frame: %d", prefetch_frame); child->GetFrame(prefetch_frame, env); // We are idle - prefetch frame prefetch_frame = -1; } } else { t.tv_sec = 0; t.tv_usec = 1000; // Allow 1ms before prefetching frame. } } // while !shutdown for (i = 0; i < FD_SETSIZE; i++) { if (s_list[i].isConnected) { closesocket(s_list[i].s); } } closesocket(m_socket); WSACleanup(); thread_running = false; _RPT0(0, "TCPServer: Client thread no longer running.\n"); }
void IrcClient::OnLine(RCString line) { smatch m; string sline = explicit_cast<string>(line); if (regex_search(sline, m, s_reMessage)) { String prefix = m[1]; String c = m[3]; String reply = m[2]; string pars = m[4]; vector<String> params; for (regex_iterator<string::const_iterator> it(pars.begin(), pars.end(), s_reParams), e; it!=e; ++it) { params.push_back((*it)[1].matched ? (*it)[1] : (*it)[2]); } if (!reply.empty()) { int nReply = atoi(reply); switch (nReply) { case RPL_CREATED: SendPendingData(); ConnectionEstablished = true; OnCreatedConnection(); break; case RPL_USERHOST: { smatch m; if (regex_search(pars, m, s_reUserhost)) { String host = m[1]; OnUserHost(host); } } break; case RPL_WHOREPLY: if (params.size() > 7) { String channel = params.at(1).substr(1); String realname = params.at(7).Split("", 2).at(1).Trim(); IrcUserInfo info = { params.at(2), params.at(3), params.at(4), params.at(5), realname }; m_whoLists[channel].push_back(info); } break; case RPL_NAMREPLY: { String channel = params.at(2).substr(1); vector<String> nicks = params.at(3).Split(); m_nameList[channel].insert(nicks.begin(), nicks.end()); } break; case RPL_ENDOFNAMES: { String channel = params.at(1).substr(1); OnNickNamesComplete(channel, m_nameList[channel]); } break; case RPL_ENDOFWHO: { String channel = params.at(1).substr(1); CWhoList::iterator it = m_whoLists.find(channel); if (it != m_whoLists.end()) { vector<IrcUserInfo> vec = it->second; m_whoLists.erase(it); OnUserListComplete(channel, vec); } } break; } } else if (!c.empty()) { if (c == "NOTICE") { if (params.size() > 0) { if (params[0] == "AUTH") { OnAuth(); } } } else if (c == "PING") { String s1 = params.at(0), s2; if (params.size() >= 2) s2 = params.at(1); OnPing(s1, s2); } } } else Throw(E_FAIL); }
// // Function: HandleIo // // Description: // This function handles the IO on a socket. First, the events signaled // on the socket are enuemrated, then the appropriate handler routine // for the event is called. // int HandleIo(THREAD_OBJ *thread, SOCKET_OBJ *sock) { WSANETWORKEVENTS nevents; int rc; // Enumerate the events rc = WSAEnumNetworkEvents( sock->s, sock->event, &nevents ); if (rc == SOCKET_ERROR) { fprintf(stderr, "HandleIo: WSAEnumNetworkEvents failed: %d\n", WSAGetLastError()); return SOCKET_ERROR; } if (nevents.lNetworkEvents & FD_READ) { // Check for read error if (nevents.iErrorCode[FD_READ_BIT] == 0) { rc = ReceivePendingData(sock); if (rc == -1) { RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } rc = SendPendingData(sock); if (rc == -1) { RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } } else { fprintf(stderr, "HandleIo: FD_READ error %d\n", nevents.iErrorCode[FD_READ_BIT]); RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } } if (nevents.lNetworkEvents & FD_WRITE) { // Check for write error if (nevents.iErrorCode[FD_WRITE_BIT] == 0) { rc = SendPendingData(sock); if (rc == -1) { RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } } else { fprintf(stderr, "HandleIo: FD_WRITE error %d\n", nevents.iErrorCode[FD_WRITE_BIT]); return SOCKET_ERROR; } } if (nevents.lNetworkEvents & FD_CLOSE) { // Check for close error if (nevents.iErrorCode[FD_CLOSE_BIT] == 0) { // Socket has been indicated as closing so make sure all the data // has been read while (1) { rc = ReceivePendingData(sock); if (rc == -1) { RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } else if (rc != 0) { continue; } else { break; } } // See if there is any data pending, if so try to send it rc = SendPendingData(sock); if (rc == -1) { RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } } else { fprintf(stderr, "HandleIo: FD_CLOSE error %d\n", nevents.iErrorCode[FD_CLOSE_BIT]); RemoveSocketObj(thread, sock); FreeSocketObj(sock); return SOCKET_ERROR; } } return NO_ERROR; }
// // Function: WindowProc // // Description: // This is the window procedure which handles the window messages for // our hidden window. It handles all the WM_SOCKET messages and performs // the correct actions for each message type (FD_READ, FD_WRITE, etc.). // LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { SOCKET_OBJ *sockobj=NULL, *newsock=NULL; int rc; if (uMsg == WM_SOCKET) { // Check for an error on the socket if (WSAGETSELECTERROR(lParam)) { // An error occured on the socket, close it down fprintf(stderr, "Socket failed with error %d\n", WSAGETSELECTERROR(lParam)); closesocket(wParam); RemoveSocketObjByHandle(wParam); } else { // Find the socket object for this event sockobj = FindSocketObj(wParam); if (sockobj == NULL) return 0; switch (WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: // Get a new object for the client socket newsock = GetSocketObj(INVALID_SOCKET); newsock->s = accept( wParam, (SOCKADDR *)&newsock->addr, &newsock->addrlen ); if (newsock->s == INVALID_SOCKET) { fprintf(stderr, "accept failed: %d\n", WSAGetLastError()); break; } InterlockedIncrement(&gCurrentConnections); // Create a socket information structure to associate with the // socket for processing I/O. InsertSocketObj(newsock); /* printf("Accepted connection from: "); PrintAddress((SOCKADDR *)&newsock->addr, newsock->addrlen); printf("\n"); */ rc = WSAAsyncSelect( newsock->s, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE ); if (rc == SOCKET_ERROR) { fprintf(stderr, "WSAAsyncSelect failed: %d\n", WSAGetLastError()); return -1; } break; case FD_READ: rc = ReceivePendingData(sockobj); if (rc == -1) { RemoveSocketObj(sockobj); break; } else if (rc != WSAEWOULDBLOCK) { PostMessage(hwnd, WM_SOCKET, wParam, FD_READ); } // // Don't break fall through and attempt to send data // case FD_WRITE: // // Send routine automatically tries to send all queued buffers. // rc = SendPendingData(sockobj); if (rc == -1) { RemoveSocketObj(sockobj); } break; case FD_CLOSE: sockobj->closing = TRUE; // // Post an FD_READ message to force another receive // This is to ensure we recv() until 0 is returned. // PostMessage(hwnd, WM_SOCKET, wParam, FD_READ); break; default: printf("Unknown message received: %d\n", WSAGETSELECTEVENT(lParam)); break; } } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }