예제 #1
0
ZQ_Error SslTcpClient::OnTrySendMsg()
{
	ZQ_Error err = OS_NoErr;
	OSMutexLocker locker(&fMutexList);
	ListElement *elem = fMsgList.first;
	if(NULL != elem)
	{
		err = SendData((char *)elem->content, elem->size);
		if(err == OS_NoErr)
		{
			RefreshTimeout();
			ListRemoveHead(&fMsgList);
			if(fMsgList.first != NULL)
				NotifySendMsg();
		}
		else//add to connect list
		{
			m_clientPool->fQueue.EnQueue(&fTaskQueueElem);
			m_clientPool->Signal(Task::kConnectEvent);
			err = OS_NotEnoughSpace;
			qtss_printf("Try to send msg.\n");
		}
	}
	return err;
}
예제 #2
0
int SSLSocket_getPendingRead()
{
	int sock = -1;

	if (pending_reads.count > 0)
	{
		sock = *(int*)(pending_reads.first->content);
		ListRemoveHead(&pending_reads);
	}
	return sock;
}
예제 #3
0
파일: Log.c 프로젝트: Frank-KunLi/DTLS_RSMB
/**
 * Add a message to the trace buffer
 * @param msg the message to add
 */
static void addToBuffer(List* buffer, char* msg)
{
	if (buffer)
	{
		int size = strlen(msg) + 1;
		char *newmsg = malloc(size);
		int max_entries = (buffer == log_buffer) ? trace_settings.max_log_entries : trace_settings.max_trace_entries;

		strcpy(newmsg, msg);
		if (buffer->count < max_entries)
			ListAppend(buffer, newmsg, size);
		else
			ListRemoveHeadAddTail(buffer, newmsg, size);
		while (buffer->count > max_entries)
			ListRemoveHead(buffer);
	}
}
예제 #4
0
/*
OS_Error SslSvrSession::GenHttpRespMsg(StrPtrLen* cmdParams, const char* content, StrPtrLen *contentType, HTTPStatusCode status)
{
	HTTPResponse	httpResponse;
	UInt32 contentLen = content==NULL?0:strlen(content);
	httpResponse.CreateResponseHeader(http11Version, status);
	httpResponse.AppendDateField();
	if(cmdParams && cmdParams->Len > 0)
	{
		httpResponse.AppendResponseHeader(httpPragmaHeader, cmdParams);
	}
	if(contentLen > 0)
	{
		httpResponse.AppendResponseHeader(httpContentTypeHeader, contentType==NULL?&HTTPBase::sContentTypeText:contentType);
		httpResponse.AppendContentLengthHeader(contentLen);
	}

	StrPtrLen* responseHeader = httpResponse.GetCompleteResponseHeader();

	PutResponse(responseHeader->Ptr, responseHeader->Len);
	if(contentLen > 0)
	{
		PutResponse(content, contentLen);
	}

	return OS_NoErr;
}
*/
SInt64 SslSvrSession::Run()
{
    EventFlags events = this->GetEvents();
	this->ForceSameThread();

	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
		return -1;

    ZQ_Error err = ZQ_NoErr;
    
    while (this->IsLiveSession())
    {
        // HTTP Session state machine. There are several well defined points in an HTTP request
        // where this session may have to return from its run function and wait for a new event.
        // Because of this, we need to track our current state and return to it.
		if(events&Task::kReadEvent)
		{
			switch(fState)
			{
			case kReadingRequest:
				{
					if ((err = fInputStream.ReadRequest(m_pssl)) == ZQ_NoErr)
					{
						// If the RequestStream returns QTSS_NoErr, it means
						// that we've read all outstanding data off the socket,
						// and still don't have a full request. Wait for more data.
	                    
						//+rt use the socket that reads the data, may be different now.
						fInputSocketP->RequestEvent(EV_RE);
						events -= Task::kReadEvent;
						break; 
					}

					if ((err != ZQ_RequestArrived) && (err != E2BIG))
					{
						// Any other error implies that the client has gone away. At this point,
						// we can't have 2 sockets, so we don't need to do the "half closed" check
						// we do below
						Assert(err > 0); 
	//					Assert(!this->IsLiveSession());
						events -= Task::kReadEvent; 
						break; 
					}

					if (err == ZQ_RequestArrived)
						fState = kProcessingRequest;
					// If we get an E2BIG, it means our buffer was overfilled.
					// In that case, we can just jump into the following state, and
					// the code their does a check for this error and returns an error.
					if (err == E2BIG)
						fState = kCleaningUp;
				}
			case kProcessingRequest:
				{
					char* pBuffer = fInputStream.GetRequestBuffer();
					UInt32 nLen = fInputStream.GetRequsetLength();
					ZQ_Error err = ZQ_NoErr;
					while(err == ZQ_NoErr && nLen > 0)
					{
						err = ProcessRecvMsg(pBuffer, nLen);
					}

					if(ZQ_NoErr == err)
					{
						fState = kReadingRequest;
						return 0;
						// Update timer.
						//fTimeoutTask.RefreshTimeout();
					} 
					else
					{
						fState = kCleaningUp;
					}
				}
				break;
			case kCleaningUp:
				{  
					// If we've gotten here, we've flushed all the data. Cleanup,
					// and wait for our next request!
					this->CleanupRequest();
					fState = kReadingRequest;
				}
				break;
			};
		}
		else if(events&Task::kWriteEvent)
		{
			OSMutexLocker locker(&fMutexList); 
			ListElement *elem = NULL; 
			int theLengthSent = 0;
			if((elem = fMsgList.first) != NULL) 
			{ 
//				err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&fMsgList); 
					if(NULL != fMsgList.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent;
		} 
		else if(events&Task::kZmqEvent)
		{	
			events -= Task::kZmqEvent;
		}
		else
		{
			return 0;
		}
	}
    
    // Make absolutely sure there are no resources being occupied by the session
    // at this point.
    this->CleanupRequest();

    // Only delete if it is ok to delete!
    if (fObjectHolders == 0)
        return -1;

    // If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    return 0;
}
예제 #5
0
SInt64 MqttServer::Run()
{
    EventFlags events = this->GetEvents();
	this->ForceSameThread();

	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
		return -1;

    ZQ_Error err = ZQ_NoErr;
    
    while (this->IsLiveSession())
    {
        // HTTP Session state machine. There are several well defined points in an HTTP request
        // where this session may have to return from its run function and wait for a new event.
        // Because of this, we need to track our current state and return to it.
		if(events&Task::kReadEvent)
		{
			if ((err = fInputStream.ReadRequest()) == ZQ_NoErr)
			{
				//+rt use the socket that reads the data, may be different now.
				fInputSocketP->RequestEvent(EV_RE);
				events -= Task::kReadEvent;
				continue; 
			}
				
			if ((err != ZQ_RequestArrived) && (err != E2BIG))
			{
				// Any other error implies that the client has gone away. At this point,
				// we can't have 2 sockets, so we don't need to do the "half closed" check
				// we do below
				Assert(err > 0); 
				Assert(!this->IsLiveSession());
				events -= Task::kReadEvent; 
				break; 
			}
				
			if (err == ZQ_RequestArrived)
			{
				char* pBuffer = fInputStream.GetRequestBuffer();
				int nLen = fInputStream.GetRequsetLength();
				ZQ_Error err = ZQ_NoErr;
				while(err == ZQ_NoErr && nLen > 0)
				{
					err = ProcessRecvMsg(pBuffer, nLen);
				}
				
				if(ZQ_NoErr == err)
				{
					err = fOutputStream.Flush();
					if (err == EAGAIN)
					{
						UInt32 datalen = 0;
						char* pData = fOutputStream.GetBufferCopy(&datalen);
						if(pData)
						{
							OSMutexLocker locker(&fMutexList); 
							ListAppend(&fMsgList, pData, datalen);
						}
						// If we get this error, we are currently flow-controlled and should
						// wait for the socket to become writeable again
						fSocket.RequestEvent(EV_RE | EV_WR);
					}
				}
				else
				{
					CleanupRequest();
				}
			};
		}
		else if(events&Task::kWriteEvent)
		{
			OSMutexLocker locker(&fMutexList); 
			ListElement *elem = NULL; 
			int theLengthSent = 0;
			if((elem = fMsgList.first) != NULL) 
			{ 
//				err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&fMsgList); 
					if(NULL != fMsgList.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent;
		} 
		else if(events&Task::kZmqEvent)
		{	
			events -= Task::kZmqEvent;
		}
		else
		{
			return 0;
		}
	}
    
    // Make absolutely sure there are no resources being occupied by the session
    // at this point.
    this->CleanupRequest();

    // Only delete if it is ok to delete!
    if (fObjectHolders == 0)
        return -1;

    // If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    return 0;
}
예제 #6
0
SInt64 RTTcp::Run()
{
	EventFlags events = this->GetEvents();
	this->ForceSameThread();
	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
	{
        if (events&Task::kTimeoutEvent) {
            LI("%s timeout \n", __FUNCTION__);
        } else {
            LI("%s kill \n", __FUNCTION__);
        }
        std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this);
        if (it != m_mapConnectObserver.end()) {
            LI("Tcp::Run find Disconnection\n");
            RTObserverConnection *conn = it->second;
            if (conn) {
                LI("Tcp::Run notify Disconnection\n");
                conn->ConnectionDisconnected();
            }
        }
		return -1;
	}


	while(this->IsLiveSession())
	{
		if(events&Task::kReadEvent)
		{
			UInt32	readed = 0;
			char	fRequestBuffer[kRequestBufferSizeInBytes];
			while(1)
			{
				readed = 0;
				// We don't have any new data, get some from the socket...
				OS_Error sockErr = fSocket.Read(fRequestBuffer, kRequestBufferSizeInBytes - 1, &readed);
				if (sockErr == EAGAIN)
					break;

				if (sockErr != OS_NoErr)
				{
					Assert(!fSocket.IsConnected());
					break;
				}

				if(readed > 0)
				{
					OnRecvData(fRequestBuffer, readed);
				}
			}

			fSocket.RequestEvent(EV_RE);
			events -= Task::kReadEvent; 
		}
		else if(events&Task::kWriteEvent)
		{
			ListElement *elem = NULL; 
			if((elem = m_listSend.first) != NULL) 
			{ 
				UInt32 theLengthSent = 0;
				OS_Error err = fSocket.Send((char*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&m_listSend); 
					if(NULL != m_listSend.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent; 
		}
		else if(events&Task::kLcsEvent)
		{
			OnLcsEvent();
			events -= Task::kLcsEvent;
		}
		else if(events&Task::kPeerEvent)
		{
			OnPeerEvent();
			events -= Task::kPeerEvent; 
		}
		else if(events&Task::kIdleEvent)
		{
			OnTickEvent();
			events -= Task::kIdleEvent; 
		}
		else
		{
			return fTickTime;
		}
	}

	// If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    std::map<RTTcp*, RTObserverConnection*>::iterator it = m_mapConnectObserver.find(this);
    if (it != m_mapConnectObserver.end()) {
        LI("Tcp::Run SessionOffline  find Disconnection\n");
        RTObserverConnection *conn = it->second;
        if (conn) {
            LI("Tcp::Run SessionOffline notify Disconnection\n");
            conn->ConnectionDisconnected();
        }
    }
    return -1;
}