示例#1
0
/* 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);
  }
}
示例#3
0
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);
  }
}
示例#4
0
文件: AdminSocket.cpp 项目: alioxp/vc
void CAdminSocket::OnSend(int nErrorCode)
{
	if (nErrorCode)
	{
		Close();
		m_pAdminInterface->Remove(this);
		return;
	}

	if( !SendPendingData() ) {
		Close();
		m_pAdminInterface->Remove(this);
		return;
	}
}
示例#5
0
文件: AdminSocket.cpp 项目: alioxp/vc
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();
}
示例#6
0
文件: AdminSocket.cpp 项目: alioxp/vc
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();
}
示例#7
0
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");
}
示例#8
0
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);
}