Esempio n. 1
0
bool CServer::OnClientInit(CServerClient* pClient)
{
    if(pClient == NULL)	return false;

    long lIndexID = pClient->GetIndexID();


    //绑定套接字到完成端口
    if( !AssociateSocketWithCP(pClient->m_hSocket,lIndexID) )
    {
        pClient->Close();
        FreeClient(pClient);
        PutErrorString(NET_MODULE,"%-15s %s",__FUNCTION__,"在函数CServer::OnConClientInitial(...)中,AssociateSocketWithCP(...)操作失败.");
        return false;
    }

    if( pClient->StartReadData() == false)
    {
        pClient->Close();
        FreeClient(pClient);
        return false;
    }

    if( pClient->IsAccept() )
        AddNewAcceptSocket(lIndexID);

    //判断接受数据是否超时,超时则关闭改套接字
    DoNewAcceptSocket();
    return true;
}
Esempio n. 2
0
//当关闭的时候
void CServer::OnClose(PER_IO_OPERATION_DATA *pPerIOData,long lIndexID)
{
    if(NULL == pPerIOData)	return;

    if(pPerIOData->OperationType == SOT_Send)
    {
        CBaseMessage* pMsg = (CBaseMessage*)pPerIOData->pParam;
        if(pMsg->RemoveRefCount() == 0)
            CBaseMessage::FreeMsg(pMsg);
    }
    else if(pPerIOData->OperationType == SOT_Receive)
    {
        m_pDBAllocator->FreeDB((CDataBlock*)pPerIOData->pParam);
    }

    CServerClient *pClient = FindClient(lIndexID);
    if(pClient)
    {
        //取消超时监视
        if(pClient->IsAccept())
            RemoveNewAcceptSocket(pClient->GetIndexID());
        pClient->OnClose();
        FreeClient(pClient);
    }
    FreeIoOper(pPerIOData);
}
Esempio n. 3
0
// error的时候调用
void CServer::OnError(PER_IO_OPERATION_DATA *pPerIOData,long lIndexID,int errorCode)
{
    if(NULL == pPerIOData)	return;
    char str[200];
    if(pPerIOData->OperationType == SOT_Send)
    {
        sprintf(str, "完成端口线程产生一次失败的发送IO操作(ErrorID:%d)。",errorCode);
        CBaseMessage* pMsg = (CBaseMessage*)pPerIOData->pParam;
        if(pMsg->RemoveRefCount() == 0)
            CBaseMessage::FreeMsg(pMsg);
    }
    else if(pPerIOData->OperationType == SOT_Receive)
    {
        sprintf(str, "完成端口线程产生一次失败的接受IO操作(ErrorID:%d)。",errorCode);
        m_pDBAllocator->FreeDB((CDataBlock*)pPerIOData->pParam);
    }


    CServerClient *pClient = FindClient(lIndexID);
    if(pClient)
    {
        //取消超时监视
        if(pClient->IsAccept())
            RemoveNewAcceptSocket(pClient->GetIndexID());
        pClient->OnClose();
        FreeClient(pClient);
    }
    FreeIoOper(pPerIOData);

    if(errorCode != 64)
    {
        PutTraceString(NET_MODULE,str);
    }
}
Esempio n. 4
0
void CloseAfterSent(proxy_client*c)
{

    /*add------------_*/
    int len;
    if(BufferListGetData(c->blist,&len)==NULL){
	FreeClient(c);
    }else{
	c->flags|=CLIENT_CLOSE_AFTER_SENT;
    }
    /*add------------_*/
}
Esempio n. 5
0
	void CServerSocket::Close()
	{
		Lock();
		CCustomClientSocket * ClientSocket;
		SetActive(false);

		for(int i =0 ;i< (int)m_ActiveClientSocketList.size();i++)
		{
			ClientSocket = m_ActiveClientSocketList[i];
			if(ClientSocket !=NULL)
			{
				FreeClient(ClientSocket);
			}
		}
		Unlock();
	  m_FreeClientPool.FreeTimeOutClient(MAX_FREE_TIMEOUT);

	}
Esempio n. 6
0
void Proxy_AcceptTcpHandler(aeEventLoop*el,int fd,void*privdata,int mask)
{
    int cport,cfd;
    char cip[128];
    cfd=anetTcpAccept(anet_error,fd,cip,&cport);
    if(cfd==AE_ERR){
	LogError("accept client connection failed:%s",anet_error);
	return;
    }
    LogInfo("Accept client from:%s:%d\n",cip,cport);

    proxy_client*c=AllocClient(cfd);

    if(c==NULL||aeCreateFileEvent(el,cfd,AE_READABLE,ReadIncome,c)==AE_ERR){
	LogError("Create event failed");
	FreeClient(c);
    }
}
Esempio n. 7
0
void CServer::OnReceive(PER_IO_OPERATION_DATA *pPerIOData,long lIndexID,long lReadNum)
{
    CServerClient* pClient = FindClient(lIndexID);

    if( pClient )
    {
        if(pClient->IsAccept())
            RemoveNewAcceptSocket(lIndexID);
        CDataBlock *pReadDB = (CDataBlock*)pPerIOData->pParam;

        //添加读数据的大小
        pClient->AddRecvSize(lReadNum);
        //设置读取数据的大小
        pReadDB->SetCurSize(lReadNum);
        //添加完成的读数据
        pClient->AddReceiveData(pPerIOData->m_nSequenceNumber,pReadDB);
        //重新开始读取数据
        if(pClient->ReadFromCompletionPort(pPerIOData,NULL) )
        {
            pClient->OnReceive();
            //如果平均每秒接受的大小超过限制值,发出错误信息.断开
            if(pClient->GetCurRecvSizePerSecond() > pClient->GetMaxRecvSizePerSecond() )
            {
                Log4c::Warn(NET_MODULE,"erro,(SocketID:%d) the current rcv data size per-second(%d) greater the max value(%d),shutdown the socket!",
                            lIndexID,pClient->GetCurRecvSizePerSecond(),pClient->GetMaxRecvSizePerSecond());
                //关闭
                pClient->Close();;
            }
        }
        else
        {
            //处理错误情况
            FreeIoOper(pPerIOData);
            pClient->OnClose();
            FreeClient(pClient);
        }
    }
    else
    {
        //处理错误情况
        FreeIoOper(pPerIOData);
    }
    return;
}
Esempio n. 8
0
void SendOutcome(aeEventLoop*el,int fd,void*privdata,int mask)
{
    LogDebug("sendoutcome");
    proxy_client*c=(proxy_client*)privdata;
    int len,nwritten=0,totwritten=0;
    char*buf;

    buf=BufferListGetData(c->blist,&len);
    if(buf==NULL){
	LogDebug("delete write event ,cause no data could sendout");
	aeDeleteFileEvent(el,fd,AE_WRITABLE);//why delete writeable event??
    }

    while(1){
	buf=BufferListGetData(c->blist,&len);
	if(buf==NULL){
	    //no data to send
	    if(c->flags&CLIENT_CLOSE_AFTER_SENT){
		FreeClient(c);
		return;
	    }
	    break;
	}
	nwritten=send(fd,buf,len,MSG_DONTWAIT);
	if(nwritten<=0) break;

	totwritten+=nwritten;
	LogDebug("Write and pop data %p %d",c->blist,nwritten);
	BufferListPop(c->blist,nwritten);
	if(totwritten>MAX_WRITE_PER_EVENT) break;
    }

    LogDebug("totwritten %d",totwritten);

    if(nwritten==-1){
	if(errno==EAGAIN){
	    nwritten=0;
	}else{
	    LogDebug("Write error %s",strerror(errno));
	    c->OnError(c);
	    return;
	}
    }
}
Esempio n. 9
0
//主动连接服务器,返回该连接的ID
//返回-1,表示失败
long CServer::Connect(LPCTSTR lpszHostAddress, UINT nHostPort,long lFlag,ulong dwTimeOut)
{
    if(!(m_bMode&1))	return -1;

    CServerClient* pConClient = AllocClient(false);
    if(pConClient == NULL)	return -1;

    if( !pConClient->CreateEx(0,NULL,SOCK_STREAM) )
    {
        PutErrorString(NET_MODULE,"%-15s Create socket bound to %s:%u FAILED, ERR_ID: %d.",__FUNCTION__, lpszHostAddress, nHostPort, GetLastError());
        return -1;
    }

    pConClient->SetFlag(lFlag);
    //设置编号
    pConClient->SetSendRevBuf();
    //设置套接字选项
    pConClient->SetSocketOpt();

    long lID = pConClient->GetIndexID();

    pConClient->SetClose(false);
    pConClient->SetShutDown(false);

    pConClient->SetParam(false,0xFFFFFFF,m_lConMaxBlockSendMsgNum,
                         m_lConPendingWrBufNum,m_lConPendingRdBufNum,
                         m_lConMaxSendSizePerSecond,m_lConMaxRecvSizePerSecond,lFlag);

    if( !Connect(pConClient,lpszHostAddress,nHostPort,dwTimeOut) )
    {
        pConClient->Close();
        FreeClient(pConClient);
        return -1;
    }

    tagSocketOper* pSocketOpera = AllocSockOper();
    pSocketOpera->Init(SCOT_Init,lID,pConClient,0);
    m_SocketOperaCommands.Push_Back(pSocketOpera);

    return lID;
}
Esempio n. 10
0
void Client::ClientEventCallback(evutil_socket_t sockfd, short event, void *userdata)
{
    Client *client = (Client*)userdata;

    if (event & EV_READ) 
    {
        int cap = client->m_intemp.capacity();
        int ret = read(sockfd, &client->m_intemp[0], cap);
    
        if (ret == -1)
        {
            if (errno != EAGAIN && errno != EINTR)
            {
                FreeClient(client);
                return;
            }
        }
        else if (ret == 0)
        {
            FreeClient(client); //client wants to leave, 
                                //so let it leave whether or not there's still any data waiting to send to it.
            return;
        }
        else
        {
            client->m_inbuf.append(client->m_intemp.c_str(), ret);
        }
    }
    
    if (event & EV_WRITE)
    {
        int ret = write(sockfd, client->m_outbuf.c_str(), client->m_outbuf.size());

        if (ret == -1)
        {
            if (errno != EAGAIN && errno != EINTR)
            {
                if (client->m_status != ON_RESPONSE)
                {
                    FreeClient(client);
                    return;
                }
            }
        }
        else
        {
            client->m_outbuf.erase(client->m_outbuf.begin(), client->m_outbuf.begin() + ret);

            //if client really want to keep write event, we can't unregister write event, even though there's nothing to send.
            if (client->m_outbuf.size() == 0 && !client->m_want_write)
            {
                client->UnsetWriteEvent();
            }
        }
    }

    // core logic, just call status machine to handle the whole thing, it's so easy :)
    if (!client->StatusMachine())
    {
        FreeClient(client);  //some error has happend, kick out the client.
    }
}
Esempio n. 11
0
// 删除一个客户端
bool CServer::FreeClient(long lSocketID)
{
    CServerClient* pClient = FindClient(lSocketID);
    FreeClient(pClient);
    return true;
}
Esempio n. 12
0
File: xsm.c Progetto: aosm/X11
static Status
RegisterClientProc(SmsConn smsConn, SmPointer managerData, char *previousId)
{
    ClientRec	*client = (ClientRec *) managerData;
    char 	*id;
    List	*cl;
    int		send_save;

    if (verbose)
    {
	printf (
	"On IceConn fd = %d, received REGISTER CLIENT [Previous Id = %s]\n",
	IceConnectionNumber (client->ice_conn),
	previousId ? previousId : "NULL");
	printf ("\n");
    }

    if (!previousId)
    {
	id = SmsGenerateClientID (smsConn);
	send_save = 1;
    }
    else
    {
	int found_match = 0;
	send_save = 1;

	for (cl = ListFirst (PendingList); cl; cl = ListNext (cl))
	{
	    PendingClient *pendClient = (PendingClient *) cl->thing;

	    if (!strcmp (pendClient->clientId, previousId))
	    {
		SetInitialProperties (client, pendClient->props);
		XtFree (pendClient->clientId);
		XtFree (pendClient->clientHostname);
		XtFree ((char *) pendClient);
		ListFreeOne (cl);
		found_match = 1;
		send_save = 0;
		break;
	    }
	}

	if (!found_match)
	{
	    for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl))
	    {
		ClientRec *rClient = (ClientRec *) cl->thing;

		if (!strcmp (rClient->clientId, previousId))
		{
		    SetInitialProperties (client, rClient->props);
		    FreeClient (rClient, False /* don't free props */);
		    ListFreeOne (cl);
		    found_match = 1;
		    send_save = 0;
		    break;
		}
	    }
	}

	if (!found_match)
	{
	    for (cl = ListFirst (RestartImmedList); cl; cl = ListNext (cl))
	    {
		ClientRec *rClient = (ClientRec *) cl->thing;

		if (!strcmp (rClient->clientId, previousId))
		{
		    SetInitialProperties (client, rClient->props);
		    FreeClient (rClient, False /* don't free props */);
		    ListFreeOne (cl);
		    found_match = 1;
		    send_save = 0;
		    break;
		}
	    }
	}

	if (!found_match)
	{
	    /*
	     * previous-id was bogus: return bad status and the client
	     * should re-register with a NULL previous-id
	     */

	    free (previousId);
	    return (0);
	}
	else
	{
	    id = previousId;
	}
    }

    SmsRegisterClientReply (smsConn, id);

    if (verbose)
    {
	printf (
	"On IceConn fd = %d, sent REGISTER CLIENT REPLY [Client Id = %s]\n",
	IceConnectionNumber (client->ice_conn), id);
	printf ("\n");
    }

    client->clientId = id;
    client->clientHostname = SmsClientHostName (smsConn);
    client->restarted = (previousId != NULL);

    if (send_save)
    {
	SmsSaveYourself (smsConn, SmSaveLocal,
	    False, SmInteractStyleNone, False);

	ListAddLast (InitialSaveList, (char *) client);
    }
    else if (client_info_visible)
    {
	/* We already have all required client info */

	UpdateClientList ();
	XawListHighlight (clientListWidget, current_client_selected);
    }

    return (1);
}
Esempio n. 13
0
File: xsm.c Progetto: aosm/X11
void
CloseDownClient(ClientRec *client)
{
    int index_deleted = 0;

    if (verbose) {
	printf ("ICE Connection closed, IceConn fd = %d\n",
		IceConnectionNumber (client->ice_conn));
	printf ("\n");
    }

    SmsCleanUp (client->smsConn);
    IceSetShutdownNegotiation (client->ice_conn, False);
    IceCloseConnection (client->ice_conn);

    client->ice_conn = NULL;
    client->smsConn = NULL;

    if (!shutdownInProgress && client_info_visible)
    {
	for (index_deleted = 0;
	    index_deleted < numClientListNames; index_deleted++)
	{
	    if (clientListRecs[index_deleted] == client)
		break;
	}
    }

    ListSearchAndFreeOne (RunningList, (char *) client);

    if (saveInProgress)
    {
	Status delStatus = ListSearchAndFreeOne (
	    WaitForSaveDoneList, (char *) client);

	if (delStatus)
	{
	    ListAddLast (FailedSaveList, (char *) client);
	    client->freeAfterBadSavePopup = True;
	}

	ListSearchAndFreeOne (WaitForInteractList, (char *) client);
	ListSearchAndFreeOne (WaitForPhase2List, (char *) client);

	if (delStatus && ListCount (WaitForSaveDoneList) == 0)
	{
	    if (ListCount (FailedSaveList) > 0 && !checkpoint_from_signal)
		PopupBadSave ();
	    else
		FinishUpSave ();
	}
	else if (ListCount (WaitForInteractList) > 0 &&
	    OkToEnterInteractPhase ())
	{
	    LetClientInteract (ListFirst (WaitForInteractList));
	}
	else if (!phase2InProgress &&
	    ListCount (WaitForPhase2List) > 0 && OkToEnterPhase2 ())
	{
	    StartPhase2 ();
	}
    }

    if (client->restartHint == SmRestartImmediately && !shutdownInProgress)
    {
	Clone (client, True /* use saved state */);

	ListAddLast (RestartImmedList, (char *) client);
    }
    else if (client->restartHint == SmRestartAnyway)
    {
	ListAddLast (RestartAnywayList, (char *) client);
    }
    else if (!client->freeAfterBadSavePopup)
    {
	FreeClient (client, True /* free props */);
    }

    if (shutdownInProgress)
    {
	if (ListCount (RunningList) == 0)
	    EndSession (0);
    }
    else if (client_info_visible)
    {
	UpdateClientList ();

	if (current_client_selected == index_deleted)
	{
	    if (current_client_selected == numClientListNames)
		current_client_selected--;

	    if (current_client_selected >= 0)
	    {
		XawListHighlight (clientListWidget, current_client_selected);
		ShowHint (clientListRecs[current_client_selected]);
		if (client_prop_visible)
		{
		    DisplayProps (clientListRecs[current_client_selected]);
		}
	    }
	}
	else
	{
	    if (index_deleted < current_client_selected)
		current_client_selected--;
	    XawListHighlight (clientListWidget, current_client_selected);
	}
    }
}
Esempio n. 14
0
/*
**  ParseConfig -- parse the config file into linked list of clients.
**
**	Parameters:
**		None.
**
**	Returns:
**		1 on success, 0 otherwise.
**
**	Side Effects:
**		- Linked list of clients will be (re)allocated.
**
**	Warnings:
**		- GetBootFiles() must be called before this routine
**		  to create a linked list of default boot files.
*/
int
ParseConfig(void)
{
	FILE *fp;
	CLIENT *client;
	u_int8_t *addr;
	char line[C_LINELEN];
	char *cp, *bcp;
	int i, j;
	int omask, linecnt = 0;

	if (BootAny)				/* ignore config file */
		return(1);

	FreeClients();				/* delete old list of clients */

	if ((fp = fopen(ConfigFile, "r")) == NULL) {
		syslog(LOG_ERR, "ParseConfig: can't open config file (%s)",
		       ConfigFile);
		return(0);
	}

	/*
	 *  We've got to block SIGHUP to prevent reconfiguration while
	 *  dealing with the linked list of Clients.  This can be done
	 *  when actually linking the new client into the list, but
	 *  this could have unexpected results if the server was HUP'd
	 *  whilst reconfiguring.  Hence, it is done here.
	 */
	omask = sigblock(sigmask(SIGHUP));

	/*
	 *  GETSTR positions `bcp' at the start of the current token,
	 *  and null terminates it.  `cp' is positioned at the start
	 *  of the next token.  spaces & commas are separators.
	 */
#define GETSTR	while (isspace(*cp) || *cp == ',') cp++;	\
		bcp = cp;					\
		while (*cp && *cp!=',' && !isspace(*cp)) cp++;	\
		if (*cp) *cp++ = '\0'

	/*
	 *  For each line, parse it into a new CLIENT struct.
	 */
	while (fgets(line, C_LINELEN, fp) != NULL) {
		linecnt++;				/* line counter */

		if (*line == '\0' || *line == '#')	/* ignore comment */
			continue;

		if ((cp = strchr(line,'#')) != NULL)	/* trash comments */
			*cp = '\0';

		cp = line;				/* init `cp' */
		GETSTR;					/* get RMP addr */
		if (bcp == cp)				/* all delimiters */
			continue;

		/*
		 *  Get an RMP address from a string.  Abort on failure.
		 */
		if ((addr = ParseAddr(bcp)) == NULL) {
			syslog(LOG_ERR,
			       "ParseConfig: line %d: can't parse <%s>",
			       linecnt, bcp);
			continue;
		}

		if ((client = NewClient(addr)) == NULL)	/* alloc new client */
			continue;

		GETSTR;					/* get first file */

		/*
		 *  If no boot files are spec'd, use the default list.
		 *  Otherwise, validate each file (`bcp') against the
		 *  list of boot-able files.
		 */
		i = 0;
		if (bcp == cp)				/* no files spec'd */
			for (; i < C_MAXFILE && BootFiles[i] != NULL; i++)
				client->files[i] = BootFiles[i];
		else {
			do {
				/*
				 *  For each boot file spec'd, make sure it's
				 *  in our list.  If so, include a pointer to
				 *  it in the CLIENT's list of boot files.
				 */
				for (j = 0; ; j++) {
					if (j==C_MAXFILE||BootFiles[j]==NULL) {
						syslog(LOG_ERR, "ParseConfig: line %d: no boot file (%s)",
						       linecnt, bcp);
						break;
					}
					if (STREQN(BootFiles[j], bcp)) {
						if (i < C_MAXFILE)
							client->files[i++] =
							    BootFiles[j];
						else
							syslog(LOG_ERR, "ParseConfig: line %d: too many boot files (%s)",
							       linecnt, bcp);
						break;
					}
				}
				GETSTR;			/* get next file */
			} while (bcp != cp);

			/*
			 *  Restricted list of boot files were spec'd,
			 *  however, none of them were found.  Since we
			 *  apparently can't let them boot "just anything",
			 *  the entire record is invalidated.
			 */
			if (i == 0) {
				FreeClient(client);
				continue;
			}
		}

		/*
		 *  Link this client into the linked list of clients.
		 *  SIGHUP has already been blocked.
		 */
		if (Clients)
			client->next = Clients;
		Clients = client;
	}

	(void) fclose(fp);				/* close config file */

	(void) sigsetmask(omask);			/* reset signal mask */

	return(1);					/* return success */
}