Пример #1
0
bool CDataQueue::ReadData(char* buffer,int wantread,int* readed)
{
	*readed=0;
	while(wantread)
	{
		char* buf;
		int canread;
		if(!WantRead(&buf,wantread,&canread))
		{
			return true;
		}
		if(canread!=wantread)
		{
			int ss=0;
		}
		memcpy(buffer,buf,canread);
		*readed+=canread;
		wantread-=canread;
		buffer+=canread;
		ReadMoveNext(canread);
	}
	return true;
}
Пример #2
0
//core algorithm !!
bool Client::StatusMachine()
{
    std::string::size_type newline;
    
    PluginStatus  plugin_status;
    RequestStatus request_status;
    
    while (true)
    {
        switch (m_status)
        {
            case BEFORE_REQUEST:  //transitional status
                if (!PluginBeforeRequest()) {
                    return false;
                }
                
                WantRead();
                SetStatus(ON_REQUEST);
                break;
            case ON_REQUEST:      //lasting status
                if (!PluginOnRequest()) {
                    return false;
                }
                
                request_status = GetHttpRequest();
                
                if (request_status == REQ_ERROR) {
                    return false;
                } 
                else if (request_status == REQ_IS_COMPLETE) {
                    SetStatus(AFTER_REQUEST);
                    break;
                }
                else {
                    return true;
                }
            case AFTER_REQUEST:   //transitional status
                if (!PluginAfterRequest()) {
                    return false;
                }
                NotWantRead();
                SetStatus(BEFORE_RESPONSE);
                break;
            case BEFORE_RESPONSE: //transitional status
                if (!PluginBeforeResponse()) {
                    return false;
                }
                WantWrite();
                SetStatus(ON_RESPONSE);
                break;
            case ON_RESPONSE:    //lasting status
                plugin_status = PluginOnResponse();
                
                if (plugin_status == ERROR) { //need to send back 500(Server Internal Error)
                    SetStatus(BEFORE_ERROR);
                    continue;
                }
                else if (plugin_status == NOT_OK) { //Plugin isn't ready, we continue with other client
                    return true;
                }
                
                //All Plugins have been finished, Send out the response.
                m_outbuf += m_response.SerializeResponse(); 
                
                SetStatus(AFTER_RESPONSE);
                break;
            case AFTER_RESPONSE:  //transitional status
                if (!PluginAfterResponse()) {
                    return false;
                }
                
                delete m_request;
                m_request = NULL;
                
                m_response.ResetResponse();
                
                NotWantWrite();
                SetStatus(BEFORE_REQUEST);
                break;
            case BEFORE_ERROR:
                m_response.ResetResponse();
                
                m_response.m_code = 500;
                m_response.m_explain = "Server Error";
                m_response.m_headers["Date"] = "Fri, 27 October 2012 15:45:00 GMT";
        
                m_outbuf += m_response.SerializeResponse();

                SetStatus(ON_ERROR);
                break;
            case ON_ERROR:
                if (!m_outbuf.size()) //keep write event to check if 500 response has been sent away
                {
                    return false;     //let the client leave, error 500 has been sent away.
                }
                return true;
        }
    }

    return true;
}
Пример #3
0
bool TcpServer::_StartUpLin()
{
#ifndef WIN32
    int loop_times = 0;
    const int timer_check_point = 10; //达到指定循环次数即开始timer检查

	while(m_bRun) 
	{
		int res = epoll_wait(m_epoll_fd, m_epev_arr, EVENT_TOTAL_COUNT, 100);
		if ( res < 0) {
            //及时退出,否则会导致 CPU 100% 
			if (EINTR == errno)
				continue;
			log_debug("epoll_wait return false, errno = %d\n", errno);
			break;
		}
		else if (0 == res) { //timeout
            loop_times = 0;
			run_timer();
		}
        else {
            //间隔一定次数即开始检查定时器的超时事件
            if (++loop_times >= timer_check_point) {
                loop_times = 0;
                //驱动定时器处理
                run_timer();
            }
        }
		
		for(int i=0; i<res; i++)
		{
			if(m_epev_arr[i].data.fd == m_listen_fd)
			{
				handle_accept();
                continue;
			}
            int fd = (uint32_t)m_epev_arr[i].data.u64; /* mask out the lower 32 bits */
            uint32 index = (uint32_t)(m_epev_arr[i].data.u64 >> 32);
            TcpHandler* s = fds[fd];
            if( s == 0 || s->get_fd_index() != index )
            {                      
                continue;       // epoll returned invalid fd 
            }
            if( m_epev_arr[i].events & ( EPOLLHUP | EPOLLERR ))
            {    
                handle_close(s);
                continue;
            }
			else if(m_epev_arr[i].events & EPOLLIN )
			{				
                if(s->handle_read() == -1)
				{
					handle_close(s);
					continue;
				}
                if( s->Writable() )
                    WantWrite(s);
			}
			else if(m_epev_arr[i].events&EPOLLOUT)
			{
				if(s->handle_output() == -1)
				{
					handle_close(s);
					continue;
				}
                if(!s->Writable())
                    WantRead(s);
			}
		}
	}
#endif 
	return true;
}
Пример #4
0
PRStatus
nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags)
{
    LOGDEBUG(("socks: DoHandshake(), state = %d", mState));

    switch (mState) {
        case SOCKS_INITIAL:
            return StartDNS(fd);
        case SOCKS_DNS_IN_PROGRESS:
            PR_SetError(PR_IN_PROGRESS_ERROR, 0);
            return PR_FAILURE;
        case SOCKS_DNS_COMPLETE:
            return ConnectToProxy(fd);
        case SOCKS_CONNECTING_TO_PROXY:
            return ContinueConnectingToProxy(fd, oflags);
        case SOCKS4_WRITE_CONNECT_REQUEST:
            if (WriteToSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            WantRead(8);
            mState = SOCKS4_READ_CONNECT_RESPONSE;
            return PR_SUCCESS;
        case SOCKS4_READ_CONNECT_RESPONSE:
            if (ReadFromSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            return ReadV4ConnectResponse();

        case SOCKS5_WRITE_AUTH_REQUEST:
            if (WriteToSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            WantRead(2);
            mState = SOCKS5_READ_AUTH_RESPONSE;
            return PR_SUCCESS;
        case SOCKS5_READ_AUTH_RESPONSE:
            if (ReadFromSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            return ReadV5AuthResponse();
        case SOCKS5_WRITE_CONNECT_REQUEST:
            if (WriteToSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;

            // The SOCKS 5 response to the connection request is variable
            // length. First, we'll read enough to tell how long the response
            // is, and will read the rest later.
            WantRead(5);
            mState = SOCKS5_READ_CONNECT_RESPONSE_TOP;
            return PR_SUCCESS;
        case SOCKS5_READ_CONNECT_RESPONSE_TOP:
            if (ReadFromSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            return ReadV5ConnectResponseTop();
        case SOCKS5_READ_CONNECT_RESPONSE_BOTTOM:
            if (ReadFromSocket(fd) != PR_SUCCESS)
                return PR_FAILURE;
            return ReadV5ConnectResponseBottom();

        case SOCKS_CONNECTED:
            LOGERROR(("socks: already connected"));
            HandshakeFinished(PR_IS_CONNECTED_ERROR);
            return PR_FAILURE;
        case SOCKS_FAILED:
            LOGERROR(("socks: already failed"));
            return PR_FAILURE;
    }

    LOGERROR(("socks: executing handshake in invalid state, %d", mState));
    HandshakeFinished(PR_INVALID_STATE_ERROR);

    return PR_FAILURE;
}
Пример #5
0
PRStatus
nsSOCKSSocketInfo::ReadV5ConnectResponseTop()
{
    uint8_t res;
    uint32_t len;

    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_CONNECT_RESPONSE_TOP,
                      "Invalid state!");
    NS_ABORT_IF_FALSE(mDataLength == 5,
                      "SOCKS 5 connection reply must be exactly 5 bytes!");

    LOGDEBUG(("socks5: checking connection reply"));

    // Check version number
    if (ReadUint8() != 0x05) {
        LOGERROR(("socks5: unexpected version in the reply"));
        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
        return PR_FAILURE;
    }

    // Check response
    res = ReadUint8();
    if (res != 0x00) {
        PRErrorCode c = PR_CONNECT_REFUSED_ERROR;

        switch (res) {
            case 0x01:
                LOGERROR(("socks5: connect failed: "
                          "01, General SOCKS server failure."));
                break;
            case 0x02:
                LOGERROR(("socks5: connect failed: "
                          "02, Connection not allowed by ruleset."));
                break;
            case 0x03:
                LOGERROR(("socks5: connect failed: 03, Network unreachable."));
                c = PR_NETWORK_UNREACHABLE_ERROR;
                break;
            case 0x04:
                LOGERROR(("socks5: connect failed: 04, Host unreachable."));
                break;
            case 0x05:
                LOGERROR(("socks5: connect failed: 05, Connection refused."));
                break;
            case 0x06:  
                LOGERROR(("socks5: connect failed: 06, TTL expired."));
                c = PR_CONNECT_TIMEOUT_ERROR;
                break;
            case 0x07:
                LOGERROR(("socks5: connect failed: "
                          "07, Command not supported."));
                break;
            case 0x08:
                LOGERROR(("socks5: connect failed: "
                          "08, Address type not supported."));
                c = PR_BAD_ADDRESS_ERROR;
                break;
            default:
                LOGERROR(("socks5: connect failed."));
                break;
        }

        HandshakeFinished(c);
        return PR_FAILURE;
    }

    if (ReadV5AddrTypeAndLength(&res, &len) != PR_SUCCESS) {
        HandshakeFinished(PR_BAD_ADDRESS_ERROR);
        return PR_FAILURE;
    }

    mState = SOCKS5_READ_CONNECT_RESPONSE_BOTTOM;
    WantRead(len + 2);

    return PR_SUCCESS;
}