Esempio n. 1
0
void bgcc::BusizProcessor::ProcessServerCallback(ReadItem *pItem, void *param, int32_t *todel, bool ssl, void* /*arg*/)
{
#ifndef _WIN32
	BGCC_TRACE("bgcc", "...Enter ServerCallback Process");
	//if(pItem->item.data)
	if(pItem->isWait){	//have wait(read message)
		TaskAsso *pT=(TaskAsso*)param;
		SOCKET sock=pT->event.fd;
		if(!pItem->err){	// err DataCallback deal
			if (ssl) {
				SSLEventCallback::RemoveFD(pT->pLoop, sock, false);
			} else {
				EventCallback::RemoveFD(pT->pLoop, sock, false);
			}
		}
		else{
			if(todel){
				*todel=0;
                if (ssl) {
                    SSLEventCallback::RemoveFD(pT->pLoop, sock, false);
                } else {
                    EventCallback::RemoveFD(pT->pLoop, sock, false);
                }
			}
		}
		pItem->psem->signal();
	}
	//pItem->psem->signal();	//default to signal
	BGCC_TRACE("bgcc", "...Leave ServerCallback Process(delete=%d)", (*todel));
#endif
}
Esempio n. 2
0
void bgcc::BusizProcessor::ProcessEnroll(ReadItem *pItem, void *param, bool ssl, void* arg)
{
	BGCC_TRACE("bgcc", "...Enter Enroll Process");
	char *p= pItem->item.data;
	SOCKET sock=INVALID_SOCKET;

#ifndef _WIN32
	TaskAsso *pT=(TaskAsso*)param;
	sock=pT->event.fd;
#endif
	
	pItem->item.memo=std::string(PROXY_NAME_PTR(p), PROXY_NAME_LEN(p));
	bgcc::ConnectionManager::get_instance()->enroll(pItem->item.memo, sock, pItem, ssl, arg);
	SocketTool::set_sndtimeout(sock, DEFAULT_SERVER_TIMEOUT);
	SocketTool::set_rcvtimeout(sock, DEFAULT_SERVER_TIMEOUT);
	pItem->isEnroll=true;

#ifndef _WIN32
	if(pT&&pT->pLoop){
		if (ssl) {
			pT->event.read_cb = SSLEventCallback::DataCallback;
		} else {
			pT->event.read_cb = EventCallback::DataCallback;
		}
        //if(pT->pLoop->add_event(&(pT->event))!=0){
        //	SocketTool::close(sock);
        //}
		pItem->pTask=pT;
	}
#endif
	
	pItem->Reset();
	BGCC_TRACE("bgcc", "...Leave Enroll Process");
}
Esempio n. 3
0
    int32_t ServiceManager::add_service(SharedPointer<IProcessor> processor) {
        BGCC_TRACE("bgcc", "Enter ServiceManager::add_service");
        std::string name;
        bool exist;
     
        if (processor.is_valid()) {
            name = processor->get_name();
        }
        else {
            BGCC_NOTICE("bgcc", "Failed to add service, because param is NULL");
            return -1;
        }

        BGCC_TRACE("bgcc", "Before Lock");
        Guard<Mutex> guard(&_mutex);
        if (!guard.is_locked()) {
            BGCC_WARN("bgcc", "Failed to lock mutex");
            return -1;
        }
        BGCC_TRACE("bgcc", "End Lock");

        exist = _name2service.find(name) != _name2service.end();
        if (!exist) {
            std::pair<name2service_map::iterator, bool> v =
                _name2service.insert(std::make_pair(name, processor));

            if (false == v.second) {
                return -1;
            }
        }

        return 0;
    }
Esempio n. 4
0
void bgcc::EventCallback::AcceptCallback(EventLoop* el, SOCKET fd, void* arg)
{
	BGCC_TRACE("bgcc", "Enter AcceptCallback(fd=%d)", fd);
	do{
		SOCKET newfd=INVALID_SOCKET;
		struct sockaddr_in sin;
		socklen_t addrlen = sizeof(struct sockaddr);
		PeerInfo tmp("", 0);

		memset(&sin, 0, addrlen);

		newfd = accept(fd, (struct sockaddr*)&sin, &addrlen);

		if (newfd >= MAXNFD) {
			SocketTool::getsockdetail(newfd, tmp, true);
			BGCC_NOTICE("bgcc", "Accept an Client From %s:%d, fd=%d", 
				tmp.GetHost().c_str(), tmp.GetPort(), newfd);
			
			BGCC_WARN("bgcc", "Too many Client. Reject the new one %s:%d, fd=%d , (max=%d)",
					tmp.GetHost().c_str(), tmp.GetPort(), newfd, MAXNFD);
			
			SocketTool::close(newfd);
			
			BGCC_TRACE("bgcc", "Leave AcceptCallback(fd=%d)", fd);
			return;
		}
	
		if (INVALID_SOCKET != newfd) {
			SocketTool::getsockdetail(newfd, tmp, true);
			BGCC_NOTICE("bgcc", "Accept an Client From %s:%d, fd=%d", 
				tmp.GetHost().c_str(), tmp.GetPort(), newfd);
			
			bgcc::ReadItem *pItem=&(Items[newfd]);
			pItem->Reset();
			pItem->isEnroll=false;
			pItem->pTask=NULL;

			Event e;
			PrepareEvent(e, newfd, arg);

            el->reset_event(newfd);

			if (el->add_event(&e) != 0) {
				BGCC_WARN("bgcc", "Add fd=%d to epoll failed(errno=%d)",
					newfd, BgccSockGetLastError());
				SocketTool::close(newfd);
			}
		}
		else{
			if(SocketTool::is_interrupt()){
				continue;
			}
			else{
				break;
			}
		}
	}while(true);
	BGCC_TRACE("bgcc", "Leave AcceptCallback(fd=%d)", fd);
}
Esempio n. 5
0
    int32_t ServiceManager::remove_service(const std::string& name) {
        BGCC_TRACE("bgcc", "Enter ServiceManager::remove_service");
        Guard<Mutex> guard(&_mutex);
        if (!guard.is_locked()) {
            return -1;
        }
        name2service_map::iterator itr = _name2service.find(name);

        if (_name2service.end() != itr) {
            _name2service.erase(itr);
        }
        BGCC_TRACE("bgcc", "Leave ServiceManager::remove_service");
        return 0;
    }
Esempio n. 6
0
    int32_t BaseProxy::__get_ticket_id(
            const std::string& fun,
            int32_t& ticket_id,
            bool belast,
            SharedPointer<IProtocol> __iprot,
            SharedPointer<IProtocol> __oprot)
    {
        int32_t ret = 0;
        int32_t tid = (int32_t)bgcc::ThreadUtil::self_id();
        std::string fname;
        MsgTypeID msg_type;
        int32_t msg_seqid;
        ret = __oprot->writeMessageBegin(_whoami.c_str(), "__get_ticket_id", bgcc::CALL, 0);
        if (ret < 0) { goto end; }
        ret = __oprot->writeInt32(tid);
        if (ret < 0) { goto end; }
        ret = __oprot->writeString(fun);
        if (ret < 0) { goto end; }
        ret = __oprot->writeBool(belast);
        if (ret < 0) { goto end; }
        __oprot->writeMessageEnd();

        ret = __iprot->readMessageBegin(fname, msg_type, msg_seqid);
        if (ret < 0) { 
            BGCC_TRACE("bgcc", "read message begin get ticket id");
            goto end;}
            if (msg_type == bgcc::EXCEPTION) {
                int32_t remote_code = 0;
                ret = __iprot->readInt32(remote_code);
                if(ret >= 0) { ret = remote_code; }
                goto end;
            }
            if (msg_type != bgcc::REPLY || fname != "__get_ticket_id") {
                ret = __iprot->skip(bgcc::IDINT32);
                if(ret < 0) { goto end;} 
                ret = __iprot->readMessageEnd();
                if(ret < 0) { goto end;} 
            }
            ret = __iprot->readInt32(ticket_id);
            BGCC_TRACE("bgcc", "ticket id %d", ticket_id);
            __iprot->readMessageEnd();
end:
            set_errno(ret);
            return ret;
    }
Esempio n. 7
0
void bgcc::BusizProcessor::ProcessHB(ReadItem *pItem, bool /*ssl*/, void* /*arg*/)
{
	BGCC_TRACE("bgcc", "...HB Process");
	if(pItem){
		//pItem->Reset();
		pItem->item.reset();
	}
	return;
} 
Esempio n. 8
0
    int32_t BaseProxy::init() {
        int32_t ncreated = 0;

#ifndef _WIN32
        signal(SIGPIPE, SIG_IGN);
#endif

        if (_service_manager) {
            struct callback_thread_arg_t arg;
            arg.proxy_name = get_name();
            arg.server_ip = _serverinfo.getIP();
            arg.server_port = _serverinfo.getPort();
            arg.service_manager = _service_manager;
            arg.sema = new Semaphore;

            _callback_thread = SharedPointer<Thread>(
                    new Thread(call_back_thread_func, &arg));
            if (_callback_thread.is_valid()) {
                BGCC_TRACE("bgcc", "before thread start");
                _callback_thread->start();
                BGCC_TRACE("bgcc", "before sema");
                arg.sema->wait();
                BGCC_TRACE("bgcc", "after sema");
            }
        }

        for (int32_t i = 0; i < _nProtocols; ++i) {
            SharedPointer<ClientSocket> connect(
                    new(std::nothrow) ClientSocket(_serverinfo.getIP(), _serverinfo.getPort()));
            if (connect.is_valid() && connect->open() == 0) {
                SharedPointer<BinaryProtocol> proto(
                        new(std::nothrow) BinaryProtocol(connect));
                if (proto.is_valid()) {
                    if (_protocols.put(proto) == 0) {
                        ++ncreated;
                    }
                }
            }
        }
        BGCC_TRACE("bgcc", "Proxy %s create %d conntections to server(%s:%d)",
                _name.c_str(), ncreated, _serverinfo.getIP().c_str(), _serverinfo.getPort());

        return ncreated;
    }
Esempio n. 9
0
AcdResultT ApServer::StopPlay(int64_t handle, const std::string& agentId,
                              const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "StopPlay AgentId = %s,handle = %"int64ld".", agentId.c_str(), handle);
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->StopPlay(handle, agentId, ctx, time_rcv);
    return ret;
}
Esempio n. 10
0
    int32_t BaseProxy::init(INIT_TYPE type) {
        int32_t ncreated = 0;

        if (_service_manager && (INIT_CALLBACK&type)) {
			if(_selector.Create()==0){
				_callback_thread = SharedPointer<Thread>(
                    new Thread( SharedPointer<CallBackTask>(
							new CallBackTask(_serverinfo.getIP(), _serverinfo.getPort(),
								_name, _service_manager, &_selector))));
	            if (_callback_thread.is_valid()) {
		            BGCC_TRACE("bgcc", "Before Start proxy_name=%s Callback Thread",
						_name.c_str());
			        _callback_thread->start();
				}
			}
			else{
				BGCC_WARN("bgcc", "Selector Create Failed, CallBackTask Start Failed");
			}
        }

		if((type&INIT_CALL)&&!_use_existing_socket){
			for (int32_t i = 0; i < _nMaxConn; ++i) {
				SharedPointer<ClientSocket> connect(
                    new(std::nothrow) ClientSocket(_serverinfo.getIP(), _serverinfo.getPort()));
	            if (connect.is_valid() && connect->open() == 0) {
		            SharedPointer<BinaryProtocol> proto(
                        new(std::nothrow) BinaryProtocol(connect));
			        if (proto.is_valid()) {
				        if (_protocols.put(proto) == 0) {
					        ++ncreated;
						}
	                }
		        }
			}
        
			BGCC_TRACE("bgcc", "Proxy %s create %d conntections to server(%s:%d)",
                _name.c_str(), ncreated, _serverinfo.getIP().c_str(), _serverinfo.getPort());
		}

        return ncreated;
    }
Esempio n. 11
0
AcdResultT ApServer::GetAssociateData(int64_t handle,
                                      const std::string& agentId,
                                      const std::string& key,
                                      std::string& value,
                                      const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "GetAssociateData AgentId = %s,handle = %"int64ld".", agentId.c_str(), handle);
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;
    ret = agentProxy->GetAssociateData(handle, agentId, key, value, ctx, time_rcv);

    return ret;
}
Esempio n. 12
0
AcdResultT ApServer::ResetAutoAnswer(int64_t handle,
                                     const std::string& agentId,
                                     bool autoAnswer,
                                     const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "ResetAutoAnswer AgentId = %s,handle = %"int64ld",autoAnswer = %d.",
               agentId.c_str(), handle, autoAnswer);
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;
    ret = agentProxy->ResetAutoAnswer(handle, agentId, autoAnswer, ctx, time_rcv);

    return ret;
}
Esempio n. 13
0
AcdResultT ApServer::ResetSkill(int64_t handle,
                                const std::string& agentId,
                                const std::string& skill,
                                const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "ResetSkill AgentId = %s,handle = %"int64ld",skill = %s.",
               agentId.c_str(), handle, skill.c_str());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;
    ret = agentProxy->ResetSkill(handle, agentId, skill, ctx, time_rcv);

    return ret;
}
Esempio n. 14
0
AcdResultT ApServer::ResetStatuschangetype(int64_t handle,
        const std::string& agentId,
        const StatusChangeT& statusChangetype,
        const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "ResetStatuschangetype AgentId = %s,handle = %"int64ld",statusChangetype = %d.",
               agentId.c_str(), handle, statusChangetype.get_value());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->ResetStatuschangetype(handle, agentId, statusChangetype, ctx, time_rcv);
    return ret;
}
Esempio n. 15
0
AcdResultT ApServer::SendDTMF(int64_t handle,
                              const std::string& agentId,
                              const std::string& digitals,
                              const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "SendDTMF AgentId = %s,handle = %"int64ld",digitals = %s.", agentId.c_str(),
               handle, digitals.c_str());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->SendDTMF(handle, agentId, digitals, ctx, time_rcv);

    return ret;
}
Esempio n. 16
0
AcdResultT ApServer::ForceSignOut(int64_t handle,
                                  const std::string& agentId,
                                  const std::string& destAgentId,
                                  const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "ForceSignOut AgentId = %s,handle = %"int64ld",destAgentId = %s.", agentId.c_str(),
               handle, destAgentId.c_str());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->ForceSignOut(handle, agentId, destAgentId, ctx, time_rcv);
    return ret;

}
Esempio n. 17
0
AcdResultT ApServer::GetAgentStatus(int64_t handle,
                                    const std::string& agentId,
                                    AgentStatusT& agentStatus,
                                    const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap", "GetAgentStatus AgentId = %s,handle = %"int64ld",agentStatus = %d.",
               agentId.c_str(), handle, agentStatus.get_value());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;
    ret = agentProxy->GetAgentStatus(handle, agentId, agentStatus, ctx, time_rcv);


    return ret;
}
Esempio n. 18
0
void bgcc::SSLEventCallback::RemoveFD(EventLoop* el, SOCKET fd, bool toclose)
{
	Event e;
	PrepareEvent(e, fd);
	if (el && el->del_event(&e) != 0) {
		BGCC_WARN("bgcc", "Del(fd=%d, toclose=%d) From Epoll Failed(%d)", 
				fd, toclose, BgccSockGetLastError());
	} else {
		BGCC_TRACE("bgcc", "Del(fd=%d, toclose=%d) From Epoll Success", fd, toclose);
	}

	if (toclose) {
		SocketTool::close(fd);
	}
}
Esempio n. 19
0
AcdResultT ApServer::ForceSignIn(int64_t handle,
                                 const std::string& agentId, const std::string& destAgentId,
                                 const std::string& agentDn, const std::string& agentPwd,
                                 const StatusChangeT& statusChangetype, bool autoAnswer, bool fcSignin,
                                 const std::string& skills, const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap",
               "ForceSignIn AgentId = %s,handle = %"int64ld",destAgentId = %s,AgentDn = %s,AgentPwd = %s,statusChangetype = %d,autoAnswer = %d,fcSignin = %d,skill = %s.",
               agentId.c_str(), handle, destAgentId.c_str(), agentDn.c_str(), agentPwd.c_str(),
               statusChangetype.get_value(), autoAnswer, fcSignin, skills.c_str());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->ForceSignIn(handle, agentId, destAgentId, agentDn, agentPwd, statusChangetype,
                                  autoAnswer, fcSignin, skills, ctx, time_rcv);
    return ret;
}
Esempio n. 20
0
AcdResultT ApServer::SwitchInsertorListen(int64_t handle,
        const std::string& agentId,
        const std::string& callerId,
        const std::string& destAgentId,
        const std::string& forCallerDispNum,
        const std::string& forCalleeDispNum,
        const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap",
               "SwitchInsertorListen AgentId = %s,handle = %"int64ld",callerId = %s,destAgentId = %s,forCallerDispNum = %s,forCalleeDispNum = %s.",
               agentId.c_str(), handle, callerId.c_str(), destAgentId.c_str(), forCallerDispNum.c_str(),
               forCalleeDispNum.c_str());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->SwitchInsertorListen(handle, agentId, callerId, destAgentId, forCallerDispNum,
                                           forCalleeDispNum, ctx, time_rcv);

    return ret;
}
Esempio n. 21
0
AcdResultT ApServer::ConferenceJoin(int64_t handle,
                                    const std::string& agentId,
                                    const std::string& callerId,
                                    const std::string& destAgentId,
                                    const std::string& forCallerDispNum,
                                    const std::string& forCalleeDispNum,
                                    const ConferenceT& conferenceType,
                                    const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap",
               "ConferenceJoin AgentId = %s,handle = %"int64ld",callerId = %s,destAgentId = %s,forCallerDispNum = %s,forCalleeDispNum = %s,conferenceType = %d.",
               agentId.c_str(), handle, callerId.c_str(), destAgentId.c_str(), forCallerDispNum.c_str(),
               forCalleeDispNum.c_str(), conferenceType.get_value());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;
    ret = agentProxy->ConferenceJoin(handle, agentId, callerId, destAgentId, forCallerDispNum,
                                     forCalleeDispNum, conferenceType, ctx, time_rcv);

    return ret;
}
Esempio n. 22
0
AcdResultT ApServer::SingleStepTransfer(int64_t handle,
                                        const std::string& agentId,
                                        const std::string& callerId,
                                        const std::string& destId,
                                        const std::string& forCallerDispNum,
                                        const std::string& forCalleeDispNum,
                                        bool isPassthrough,
                                        const CallTypeT& transferType,
                                        const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap",
               "SingleStepTransfer AgentId = %s,handle = %"int64ld",callerId = %s,destId = %s,forCallerDispNum = %s,forCalleeDispNum = %s,isPassthrough = %d,transferType = %d.",
               agentId.c_str(), handle, callerId.c_str(), destId.c_str(), forCallerDispNum.c_str(),
               forCalleeDispNum.c_str(), isPassthrough, transferType.get_value());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->SingleStepTransfer(handle, agentId, callerId, destId, forCallerDispNum,
                                         forCalleeDispNum, isPassthrough, transferType, ctx, time_rcv);

    return ret;
}
Esempio n. 23
0
AcdResultT ApServer::OutboundCall(int64_t handle,
                                  const std::string& agentId,
                                  const std::string& callerId,
                                  const std::string& destId,
                                  const std::string& forCallerDispNum,
                                  const std::string& forCalleeDispNum,
                                  int32_t timeout,
                                  const CallModeT& callMode,
                                  const CallTypeT& callType,
                                  const std::map<std::string, std::string>& ctx) {
    BGCC_TRACE("ap",
               "OutboundCall AgentId = %s,handle = %"int64ld",callerId = %s,destId = %s,forCallerDispNum = %s,forCalleeDispNum = %s,timeout = %d,callMode = %d,callType = %d.",
               agentId.c_str(), handle, callerId.c_str(), destId.c_str(), forCallerDispNum.c_str(),
               forCalleeDispNum.c_str(),
               timeout, callMode.get_value(), callType.get_value());
    uint64_t time_rcv = TimeUtil::get_timestamp_ms();
    AgentProxy* agentProxy = AgentProxy::Instance();
    AcdResultT ret;

    ret = agentProxy->OutboundCall(handle, agentId, callerId, destId, forCallerDispNum,
                                   forCalleeDispNum, timeout, callMode, callType, ctx, time_rcv);

    return ret;
}
Esempio n. 24
0
void bgcc::SSLEventCallback::SSLAcceptCallback(EventLoop* el, SOCKET fd, void* arg)
{
	int ret;
	Event e;
	SSLEventCallbackArg* newCallbackArg = (SSLEventCallbackArg*)arg;

	BGCC_TRACE("bgcc", "Enter SSL SSLAcceptCallback(fd=%d)", fd);

	ret = SSL_accept(newCallbackArg->ssl);
	switch(SSL_get_error(newCallbackArg->ssl, ret)) {
		case SSL_ERROR_NONE:
			BGCC_TRACE("bgcc", "ERROR NONE");
			PrepareEvent(e, fd, newCallbackArg);

            if (el->del_event(&e) != 0 || el->add_event(&e) != 0) {
				SSL_shutdown(newCallbackArg->ssl);
				BGCC_DEBUG("bgcc", "Memory SSL free: %p", newCallbackArg->ssl);
				SSL_free(newCallbackArg->ssl);
				newCallbackArg->ssl = NULL;
				RemoveFD(el, fd, true);
				BGCC_TRACE("bgcc", "ssl add_event failed");
			}
			break;
		case SSL_ERROR_WANT_ACCEPT:
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			BGCC_TRACE("bgcc", "WANT ACCPET");
			break;
		default:
			BGCC_TRACE("bgcc", "DEFAULT");
			SSL_shutdown(newCallbackArg->ssl);
			BGCC_DEBUG("bgcc", "Memory SSL free: %p", newCallbackArg->ssl);
			SSL_free(newCallbackArg->ssl);
			newCallbackArg->ssl = NULL;
			RemoveFD(el, fd, true);
			break;
	}

	BGCC_TRACE("bgcc", "Leave SSL SSLAcceptCallback(fd=%d)", fd);
}
Esempio n. 25
0
void bgcc::SSLEventCallback::AcceptCallback(EventLoop* el, SOCKET fd, void* arg)
{
	BGCC_TRACE("bgcc", "Enter SSL AcceptCallback(fd=%d)", fd);
	do {
		SOCKET newfd = INVALID_SOCKET;
		struct sockaddr_in sin;
		socklen_t addrlen = sizeof(struct sockaddr);
		PeerInfo tmp("", 0);

		memset(&sin, 0, addrlen);

		newfd = accept(fd, (struct sockaddr*)&sin, &addrlen);
		if (INVALID_SOCKET != newfd) {
			SocketTool::getsockdetail(newfd, tmp, true);
			BGCC_NOTICE("bgcc", "Accept an Client From %s:%d, fd=%d",
					tmp.GetHost().c_str(), tmp.GetPort(), newfd);
		} else {
			if (SocketTool::is_interrupt()) {
				continue;
			} else {
				break;
			}
		}

		if (newfd >= MAXNFD) {
			BGCC_WARN("bgcc", "Too many client. Reject client %s:%d, fd=%d, (max=%d)",
					tmp.GetHost().c_str(), tmp.GetPort(), newfd, MAXNFD);
			SocketTool::close(newfd);
			BGCC_TRACE("bgcc", "Leave SSL AcceptCallback(fd=%d)", fd);
			return;
		} else {
			bgcc::ReadItem* pItem = &(Items[newfd]);
			pItem->Reset();
			pItem->isEnroll = false;
			pItem->pTask = NULL;

			SSLEventCallbackArg* callbackArg = (SSLEventCallbackArg*)arg;
			SSLEventCallbackArg* newCallbackArg = &args[newfd];
			newCallbackArg->arg = callbackArg->arg;
			newCallbackArg->ssl = SSL_new(g_ssl_ctx);
			BGCC_DEBUG("bgcc", "Memory new: %p", newCallbackArg->ssl);
			if (!newCallbackArg->ssl) {
				BGCC_WARN("bgcc", "new ssl failed. close fd=%d", newfd);
				SocketTool::close(newfd);
				break;
			}

			SSL_set_fd(newCallbackArg->ssl, newfd);

			Event e;
			PrepareEvent(e, newfd, newCallbackArg);
			e.read_cb = SSLAcceptCallback;

			if (el->add_event(&e) != 0) {
				SSL_shutdown(newCallbackArg->ssl);
				BGCC_DEBUG("bgcc", "Memory SSL free: %p", newCallbackArg->ssl);
				SSL_free(newCallbackArg->ssl);
				newCallbackArg->ssl = NULL;
				SocketTool::close(newfd);
				BGCC_TRACE("bgcc", "ssl add_event failed");
			}
		}
	} while (true);
	BGCC_TRACE("bgcc", "Leave SSL AcceptCallback(fd=%d)", fd);
}
Esempio n. 26
0
int32_t fs_opr_t::get_event(fs_event_t& event, uint32_t timeout) {
    FUNC_BEGIN();
    bzero(&event, sizeof(event));
    (void)fs_resp;

    //if(esl_recv_timed(&_handle,timeout*1000)==ESL_SUCCESS){
    //check_q If set to 1, will check the handle queue (handle->race_event) and return the last
    //event from it
    //
    //没太看明白 稍微看了下源码,好像是set为1则取队列中的。不设置为1则可能丢事件,需要再次确定
    //if(esl_recv_event_timed(&_handle, timeout, 1, NULL)==ESL_SUCCESS){
    //使用带超时的接口会导致获取的fsevent事件内容为空,具体原因未知
    if (esl_recv_event_timed(&_handle, 0, 1, NULL) == ESL_SUCCESS) {
        event.timestamp = 0;
        //拷贝事件到event中
        get_head_val("Event-Name", event.name, LEN_64);

        if (IMS_SUCCESS == get_head_val("Event-Date-Timestamp", szcmd, LEN_512)) {
            event.timestamp = atoll(szcmd);
        } else {
            WARNING_LOG("get head_val Event-Date-Timestamp failed.!");
        }

        if (strcasecmp(event.name, "HEARTBEAT") == 0) {
            event.datatype = EDT_HEARTBEAT;

            if (IMS_SUCCESS == get_head_val("Session-Since-Startup", szcmd, LEN_512)) {
                event.event_data.heartbeat.all_session = (uint32_t)atoi(szcmd);
            }

            if (IMS_SUCCESS == get_head_val("Session-Count", szcmd, LEN_512)) {
                event.event_data.heartbeat.cur_session = (uint32_t)atoi(szcmd);
            }

            if (IMS_SUCCESS == get_head_val("Idle-CPU", szcmd, LEN_512)) {
                event.event_data.heartbeat.cpu_idle = (uint32_t)atoi(szcmd);
            }
        } else {
            event.datatype = EDT_NORMAL;
            event.event_data.normal.call_direction = FCD_UNKNOWN;
            event.event_data.normal.call_state = FCS_UNKNOWN;

            if (strcasecmp(event.name, "BACKGROUND_JOB") == 0) {
                event.event_data.normal.call_direction = FCD_OUTBOUND;
                char* fs_resp = esl_event_get_body(_handle.last_ievent);

                if (fs_resp && !is_result_ok(fs_resp)) {
                    strncpy(event.event_data.normal.reason, fs_resp + 5, LEN_128);
                    char* fs_tmp = event.event_data.normal.reason;

                    while (fs_tmp && *fs_tmp) {
                        if (*fs_tmp == '\n') {
                            *fs_tmp = '\0';
                            break;
                        }

                        fs_tmp++;
                    }

                    char tmp[LEN_512 + 1] = {0};
                    get_head_val("Job-Command-Arg", tmp, LEN_512);

                    {
                        //uuid_record error
                        char cmd[LEN_512 + 1] = {0};
                        get_head_val("Job-Command", cmd, LEN_512);
                        DEBUG_LOG("BACKGROUND_JOB: Job-Command(=%s)", cmd);

                        if (0 == strncasecmp(cmd, "uuid_record", 11)) {
                            WARNING_LOG("uuid_record failed, command-arg(=%s)", tmp);
                            continue;
                        }
                    }

                    {
                        char* tmp_start = strstr(tmp, "}");

                        if (tmp_start) {
                            char* tmp_end = strstr(tmp_start, " ");

                            if (tmp_end && tmp_end > tmp_start) {
                                strncpy(event.event_data.normal.channel_name, tmp_start + 1, tmp_end - tmp_start - 1);
                            }
                        }

                    }

                    {
                        char* tmp_sz = strstr(tmp, "IMSDATA=");

                        if (tmp_sz) {
                            tmp_sz += 8;
                            char* id_end = tmp_sz;

                            while (id_end && isdigit(*id_end)) {
                                id_end++;
                            }

                            if (id_end) {
                                *id_end = '\0';
                                event.sessionid = atoll(tmp_sz);
                                strncpy(event.name, "OPERATION_FAILED", LEN_64);
                            }
                        }
                    }
                } else {
                    ret = IMS_FAIL_TIMEOUT;
                    break;
                }
            } else {
                get_head_val("Unique-ID", event.event_data.normal.uuid, LEN_64);
                get_head_val("Caller-Caller-ID-Number", event.event_data.normal.caller_no, LEN_64);
                get_head_val("Caller-Destination-Number", event.event_data.normal.called_no, LEN_64);
                get_head_val("Channel-Name", event.event_data.normal.channel_name, LEN_64);
                std::string deviceno;

                if (strncasecmp(event.event_data.normal.channel_name, "freetdm", 7) == 0) {
                    get_head_val("variable_channel_name", event.event_data.normal.channel_name, LEN_64);
                }

                if (ims_tool_t::chlname2no(event.event_data.normal.channel_name, deviceno)) {
                    strncpy(event.event_data.normal.deviceno, deviceno.c_str(), LEN_64);
                } else {
                    event.event_data.normal.deviceno[0] = '\0';
                }

                get_head_val("Other-Leg-Unique-ID", event.event_data.normal.other_uuid, LEN_64);
                get_head_val("Other-Leg-Caller-ID-Number", event.event_data.normal.other_caller_no, LEN_64);
                get_head_val("Other-Leg-Destination-Number", event.event_data.normal.other_called_no, LEN_64);
                get_head_val("Other-Leg-Channel-Name", event.event_data.normal.other_channel_name, LEN_64);
                deviceno = "";

                if ('\0' != event.event_data.normal.other_channel_name[0]
                        && ims_tool_t::chlname2no(event.event_data.normal.other_channel_name, deviceno)) {
                    strncpy(event.event_data.normal.other_deviceno, deviceno.c_str(), LEN_64);
                } else {
                    event.event_data.normal.other_deviceno[0] = '\0';
                }

                get_head_val("Application", event.event_data.normal.application, LEN_32);
                get_head_val("Application-Data", event.event_data.normal.application_data, LEN_64);
                get_head_val("Application-Response", event.event_data.normal.application_resp, LEN_128);
                get_head_val("Hangup-Cause", event.event_data.normal.reason, LEN_128);

                if (IMS_SUCCESS == get_var("IMSDATA", szcmd, LEN_512)) {
                    event.sessionid = atoll(szcmd);
                } else {
                    event.sessionid = 0;
                }

                if (IMS_SUCCESS == get_head_val("Call-Direction", szcmd, LEN_512)) {
                    if (strcasecmp(szcmd, "outbound") == 0) {
                        event.event_data.normal.call_direction = FCD_OUTBOUND;
                    } else if (strcasecmp(szcmd, "inbound") == 0) {
                        event.event_data.normal.call_direction = FCD_INBOUND;
                    }
                }

                if (IMS_SUCCESS == get_head_val("Answer-State", szcmd, LEN_512)) {
                    if (strcasecmp(szcmd, "answered") == 0) {
                        event.event_data.normal.call_state = FCS_ANSWERED;
                    } else if (strcasecmp(szcmd, "early") == 0) {
                        event.event_data.normal.call_state = FCS_EARLY;
                    } else if (strcasecmp(szcmd, "ringing") == 0) {
                        event.event_data.normal.call_state = FCS_RING;
                    }
                }

                if (strcasecmp(event.name, "CUSTOM") == 0) {
                    char tmp[LEN_128 + 1] = {0};
                    get_head_val("Event-Subclass", tmp, LEN_128);

                    if (strcasecmp(tmp, "conference::maintenance") == 0) {
                        get_head_val("Action", tmp, LEN_128);

                        if (strcasecmp(tmp, "add-member") == 0) {
                            strncpy(event.name, "CONFERENCE_JOIN", LEN_64);
                            get_head_val("Member-ID", event.event_data.normal.ims_data, LEN_128);
                        } else if (strcasecmp(tmp, "mute-member") == 0) {
                            strncpy(event.name, "CONFERENCE_MUTE", LEN_64);
                        } else if (strcasecmp(tmp, "unmute-member") == 0) {
                            strncpy(event.name, "CONFERENCE_UNMUTE", LEN_64);
                        } else {
                            ret = IMS_FAIL_TIMEOUT;
                            break;
                        }
                    } else {
                        ret = IMS_FAIL_TIMEOUT;
                        break;
                    }
                } else if (strcasecmp(event.name, "RECORD_START") == 0) {
                    get_head_val("Record-File-Path", event.event_data.normal.ims_data, LEN_128);

                    if (strlen(event.event_data.normal.ims_data) > strlen(_recordbase)) {
                        char* ptmp = (char*)(event.event_data.normal.ims_data) + strlen(_recordbase);

                        while (ptmp && *ptmp == '/') {
                            ++ptmp;
                        }

                        std::string new_file = ptmp;
                        strncpy(event.event_data.normal.ims_data, new_file.c_str(), LEN_128);
                    }
                }
            }


            std::ostringstream ostm;
            ostm << std::endl;
            ostm << "===========================FS EVENT============================" << std::endl;
            ostm << "ID            : " << _fs_no << std::endl;
            ostm << "Address       : " << _address << ":" << _port << std::endl;
            ostm << "Time          : " << event.timestamp << std::endl;
            ostm << "SessionID     : " << event.sessionid << std::endl;
            ostm << "IMSDATA       : " << event.event_data.normal.ims_data << std::endl;
            ostm << "Name          : " << event.name << std::endl;
            ostm << "Type          : Normal" << std::endl;
            ostm << "Uuid          : " << event.event_data.normal.uuid << std::endl;;
            ostm << "CallerNo      : " << event.event_data.normal.caller_no << std::endl;;
            ostm << "CalledNo      : " << event.event_data.normal.called_no << std::endl;
            ostm << "ChannelName   : " << event.event_data.normal.channel_name << std::endl;
            ostm << "Direction     : " << event.event_data.normal.call_direction << std::endl;
            ostm << "CallState     : " << event.event_data.normal.call_state << std::endl;
            ostm << "App:          : " << event.event_data.normal.application << std::endl;
            ostm << "App_Data      : " << event.event_data.normal.application_data << std::endl;
            ostm << "App_Resp      : " << event.event_data.normal.application_resp << std::endl;
            ostm << "Other_Uuid    : " << event.event_data.normal.other_uuid << std::endl;
            ostm << "Other_Caller  : " << event.event_data.normal.other_caller_no << std::endl;
            ostm << "Other_Called  : " << event.event_data.normal.other_called_no << std::endl;
            ostm << "Other_Channel : " << event.event_data.normal.other_channel_name << std::endl;
            ostm << "Reason        : " << event.event_data.normal.reason << std::endl;
            ostm << "============================End Event============================" << std::endl;

            BGCC_TRACE("fsevent", "%s", ostm.str().c_str());
        }

        ret = IMS_SUCCESS;
        break;
    }

    //链接是好都么
    if (is_handle_valid()) {
        ret = IMS_FAIL_TIMEOUT;
        break;
    } else { // if(IMS_SUCCESS!=connect(_address,_port,_pswd,true)){
        WARNING_LOG("recv event failed(connect err)");
        ret = IMS_FAIL_CONNECT;
        break;
    }

    FUNC_END();
}
Esempio n. 27
0
void bgcc::EventCallback::DataCallback(EventLoop* el, SOCKET fd, void* arg)
{
	int32_t ret=0;
	char *p=NULL;

	bgcc::Mempool* mempool = bgcc::Mempool::get_instance();

	bgcc::ReadItem *pItem=&(Items[fd]);
	reading_item_t& item = pItem->item;
	p = item.head_buf;
	if(S_SIZE_READING == item.state){
		p = item.head_buf;
	}
	else if(S_DATA_READING == item.state){
		p = item.data;
	}

	BGCC_TRACE("bgcc", "Enter DataCallback(fd=%d)", fd);
	while (true){
		ret = recv(fd, p+item.nread, item.nexpected, 0);
		if(ret>0){
			item.nread += ret;
			item.nexpected -= ret;
			if (0 == item.nexpected) {
				if (S_SIZE_READING == item.state) {
					if (item.head_buf[0] != 'b'
							|| item.head_buf[1] != 'g'
							|| item.head_buf[2] != 'c'
							|| item.head_buf[3] != 'P') {
						BGCC_WARN("bgcc", "invalid bgcc header(fd=%d)", fd);
						pItem->err = -1;
						break;
					}
					item.state = S_DATA_READING;
					item.nexpected = BODY_LEN(p);

					if (item.nexpected < 0){
						BGCC_WARN("bgcc", "Message body length=%d too short, remove from epoll",
								item.nexpected);
						break;
					}
					else if(0==item.nexpected){
						BGCC_TRACE("bgcc", "Empty body Package");
						break;
					}

					item.data = (char*)mempool->get_mem_block(item.nexpected);
					p = item.data;
					item.nread = 0;
					continue;
				}
				else if (S_DATA_READING == item.state) {
					pItem->err=0;
					break;
				}
			}
		}
		else if (ret<0) {
			if (SocketTool::is_interrupt()) {
				continue;
			}
			else if (SocketTool::is_wouldblock()) {
				return;
			}
			else {
				pItem->err=BgccSockGetLastError();
				BGCC_WARN("bgcc", "Recv Failed. fd=%d errno=%d", 
						fd, pItem->err);
				break;
			}
		}
		else{
			pItem->err=-1;
			BGCC_TRACE("bgcc", "Recv Return 0. fd=%d ", fd);
			break;
		}
	}

	EpollServer *pArg=(EpollServer*)arg;
	TaskAsso *pT= (pArg?pArg->Tasks+fd:NULL);
	pT->pLoop=el;
	pT->pServer=(EpollServer*)arg;
	pT->pItem=pItem;
	PrepareEvent(pT->event, fd, arg);
	pItem->pTask=pT;

	int32_t todel=1;

        // save pItem->err and pItem->isEnroll
        // because pItem may be invalid after Process when err && isEnroll
        int32_t err = pItem->err;
        bool is_enroll = pItem->isEnroll;

	BusizProcessor::Process(pItem, pT, item.nread, &todel);

    if (err) {
        if (is_enroll) {//put_conn call RemoveFD, so here not to call RemoveFD
			if(todel){
				BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
				SharedPointer<BinaryProtocol> proto = SharedPointer<BinaryProtocol>(
					new BinaryProtocol( SharedPointer<ServerPeerSocket>(
							new ServerPeerSocket(fd)
							)));
				SharedPointer<ConnInfo> info=SharedPointer<ConnInfo>(
					new ConnInfo(proto, pItem)
					);
				if(proto.is_valid()&&info.is_valid()){
					bgcc::ConnectionManager::get_instance()->put_connection(pItem->item.memo, info, true);
				}
            }
		}
		else{
			BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
			RemoveFD(el,fd);
		}

	}
	BGCC_TRACE("bgcc", "Leave DataCallback(fd=%d)", fd);
}
Esempio n. 28
0
    void* call_back_thread_func(void* param) {
        BGCC_TRACE("bgcc", "enroll self");


        callback_thread_arg_t* arg = (callback_thread_arg_t*)param;
        std::string proxy_name = arg->proxy_name;
        std::string server_ip = arg->server_ip;
        int32_t server_port = arg->server_port;
        ServiceManager* service_manager = arg->service_manager;
        Semaphore* sema = arg->sema;

        SharedPointer<ClientSocket> connect;
        SharedPointer<BinaryProtocol> proto;

#ifndef _WIN32
        int32_t ep = epoll_create(1);
        struct epoll_event ee;
        struct epoll_event revents[1];

#endif
RECON:
        sema->signal();
        connect = SharedPointer<ClientSocket>(
                new(std::nothrow) ClientSocket(server_ip, server_port));

        connect->open();

        connect->set_recv_timeout(60*60*24*30);
        proto = SharedPointer<BinaryProtocol>(
                new(std::nothrow) BinaryProtocol(connect));
        int32_t ret = 0;

        ret = proto->writeMessageBegin("bgcc::BaseProcessor_enroll", "__enroll", bgcc::CALL, 0);
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
        ret = proto->writeString(proxy_name);
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
        ret = proto->writeMessageEnd();
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
#ifndef _WIN32
        ee.data.fd = connect->get_socket();
        ee.events = EPOLLIN;
        epoll_ctl(ep, EPOLL_CTL_ADD, connect->get_socket(), &ee);
#endif
        while (true) {
#ifndef _WIN32
            int32_t nevent = epoll_wait(ep, revents, 1, -1);
            BGCC_TRACE("bgcc", "epoll_wait return %d", nevent);
            if (nevent >= 1) {
#endif
                char buffer[BUFSIZ];
                int32_t xxret;
                xxret = connect->read(buffer, 20);
                BGCC_TRACE("bgcc", "ret value read %d", xxret);
                if (0 != xxret) {
#ifndef _WIN32
                    epoll_ctl(ep, EPOLL_CTL_DEL, connect->get_socket(), &ee);
#endif
                    bgcc::TimeUtil::safe_sleep_s(1);
                    goto RECON;
                }
                int32_t body_len = (int32_t)ntohl(*(uint32_t*)(buffer +16));
                BGCC_TRACE("bgcc", "body size %d", body_len);
                char body[BUFSIZ];
                xxret = connect->read(body, body_len);
                BGCC_TRACE("bgcc", "body ret value read %d", xxret);
                if (0 != xxret) {
#ifndef _WIN32
                    epoll_ctl(ep, EPOLL_CTL_DEL, connect->get_socket(), &ee);
#endif
                    bgcc::TimeUtil::safe_sleep_s(1);
                    goto RECON;
                }
                int32_t processor_name_len = (int32_t)ntohl(*(uint32_t*)(body));
                std::string processor_name(body + 4, processor_name_len);
                SharedPointer<IProcessor> processor =
                    service_manager->get_service(processor_name);
                if (processor.is_valid()) {
                    processor->process(
                            body + 4 + processor_name_len,
                            body_len - 4 - processor_name_len,
                            proto);
                }

                /* added for handling unexist service*/
                else {
                    processor = service_manager->get_service("._baseservice_2012");
                    if (processor.is_valid()) {
                        SharedPointer<BinaryProtocol> bp(new BinaryProtocol(SharedPointer<ITransport>(NULL)));

                        bp->writeMessageBegin("xx", "__service_not_found", bgcc::CALL, 0);
                        bp->writeInt32(0);
                        bp->writeString("__service_not_found");
                        bp->writeBool(false);

                        void* data = NULL;
                        int32_t head_body_size;
                        NBDataBuffer* db = bp->get_data_buffer();
                        db->get_data(&data, head_body_size);
                        processor->process(
                                (char*)data + 20 + 4 + 2,
                                head_body_size - 20 - 4 - 2,
                                proto);

                    }
                }
#ifndef _WIN32
            }
#endif
        }

//#ifdef _WIN32
        return NULL;
//#endif

    }
Esempio n. 29
0
void bgcc::BusizProcessor::ProcessUser(ReadItem *pItem, const std::string &name, void *param, bool ssl, void* arg)
{
	BGCC_TRACE("bgcc", "...Enter User Process");
	char *p= pItem->item.data;
	static char buffer[MAX_DEFAULT_LEN]={0};
	int32_t buffer_size=MAX_DEFAULT_LEN;
	bgcc::ServiceManager* service_manager = NULL;
	bgcc::ThreadPool* thread_pool = NULL;
	SOCKET sock=INVALID_SOCKET;	

#ifndef _WIN32
	TaskAsso *pT=(TaskAsso*)param;
	EpollServer* pServer=(EpollServer*)pT->pServer;
	service_manager = pServer->get_service_manager();
	thread_pool = pServer->get_thread_pool();
	sock=pT->event.fd;
#endif

	SharedPointer<IProcessor> processor = service_manager->get_service(name);
	if(!processor.is_valid()){
		processor = service_manager->get_service(DEF_SERVICE);
		if(processor.is_valid()){
			p=NULL;
			if(Fake::fake_default_body(buffer, buffer_size)){
				p=buffer;
			
				BGCC_WARN("bgcc", "...Cannot find processor %s to use default service", 
					name.c_str());
			}
		}
	}

	if (processor.is_valid() && p) {
#ifndef _WIN32
		if (ssl) {
			SSLEventCallback::RemoveFD(pT->pLoop, sock, false);
		} else {
			EventCallback::RemoveFD(pT->pLoop, sock, false);
		}
#endif
		ServerPeerSocket* server_peer_socket = NULL;
		
		if (ssl) {
#ifndef _WIN32
            SSLEventCallbackArg* callbackArg = (SSLEventCallbackArg*)arg;
			server_peer_socket = new SSLServerPeerSocket(&(callbackArg->ssl), sock);
#endif
		} else {
			server_peer_socket = new ServerPeerSocket(sock);
		}

        if (!server_peer_socket->GetPeerInfo().is_valid()) {
            BGCC_WARN("bgcc", "Broken socket, fd=%d", sock);
            return;
        }

		SharedPointer<ITransport> trans(server_peer_socket);
		SharedPointer<IProtocol> proto(new BinaryProtocol(trans));
		SharedPointer<Runnable> task(new ServerTask(processor, p, 
					(p==pItem->item.data?pItem->item.nread:buffer_size), proto, param));

		if(!thread_pool->addTask(task)){
			BGCC_WARN("bgcc", "...Add Task Failed(fd=%d, processor=%s)", sock, name.c_str());
		}
	}
	else{
		BGCC_WARN("bgcc", "...Cannot find Any Processor do nothing");
	}
	BGCC_TRACE("bgcc", "...Leave User Process");
}
Esempio n. 30
0
std::vector<bgcc::NetUtil::ServerNode>::iterator NetUtil::net_check(
    std::vector<ServerNode>& server_node_list)
{
    int64_t count_time = 0;
    int64_t temp_time = 0; 
    int64_t min_time = -1; 
    int64_t flag = 0;
    std::vector<ServerNode>::iterator iter;
    iter = server_node_list.end();
    if (server_node_list.size() == 0) {
        return server_node_list.end();
    }

    struct sockaddr_in client_addr;
    SocketTool::init();

    for (std::vector<NetUtil::ServerNode>::iterator it = server_node_list.begin();
                it != server_node_list.end();
                ++it) {
        for (int j = 0; j < 3; ++j) { 
            SOCKET sock;
            memset(&client_addr, 0, sizeof(client_addr));
            fd_set  write_set; 
            timeval to; 
            to.tv_sec = 1; 
            to.tv_usec = 0; 
            char  error = '\0';
            int   len = sizeof(char); 

            if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                BGCC_WARN("bgcc", "create socket fail ip=%s, port=%d.", it->ip.c_str(), it->port);
                break;
            }
            struct sockaddr_in server_addr;
            memset(&server_addr, 0, sizeof(server_addr));
            server_addr.sin_family = AF_INET; 
            server_addr.sin_port = htons(it->port);    
#ifndef  _WIN32
            server_addr.sin_addr.s_addr = inet_addr(it->ip.c_str());
#else
            server_addr.sin_addr.S_un.S_addr = inet_addr(it->ip.c_str());
#endif
            SocketTool::set_nonblock(sock, 1);
            temp_time = TimeUtil::get_timestamp_us();
            if (connect(sock, (struct sockaddr *)&server_addr, sizeof(sockaddr_in)) != 0) { 

                FD_ZERO(&write_set); 
                FD_SET(sock, &write_set); 

                if (select(sock + 1, NULL, &write_set, NULL, &to) > 0) { 
                    getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, (socklen_t*)&len);  
                    if (error == 0) {
                        flag = 0;
                        BGCC_TRACE("bgcc", "connect successful ip=%s, port=%d.", 
                                it->ip.c_str(), 
                                it->port);
                        SocketTool::close(sock);
                    } 
                    else { 
                        flag = -1;
                        BGCC_WARN("bgcc", "connect fail ip=%s, port=%d.", it->ip.c_str(), it->port);
                        break;
                    }
                } else { 
                    flag = -1;
                    BGCC_WARN("bgcc", "connect fail ip=%s, port=%d.", it->ip.c_str(), it->port);
                    break;
                } 
            } 
            else {
                flag = 0;
                BGCC_TRACE("bgcc", "connect successful ip=%s, port=%d.", it->ip.c_str(), it->port);
                SocketTool::close(sock);
            }

            temp_time = TimeUtil::get_timestamp_us() - temp_time;
            count_time += temp_time;
            BGCC_TRACE("bgcc", "%d times (ip=%s, port=%d) need %ld us.", 
                j, 
                it->ip.c_str(), 
                it->port, 
                temp_time); 
        }
        if (flag == 0) {
            if (min_time == -1 || (count_time < min_time && min_time != -1)) {
                min_time = count_time;
                iter = it;
                BGCC_TRACE("bgcc", "(%s, %d) sum need %ld us.", 
                    iter->ip.c_str(), 
                    iter->port, 
                    count_time);
            }
        } else {
            BGCC_TRACE("bgcc", "connect fail throw ip = %s, port=%d.", it->ip.c_str(), it->port);
        }

        count_time = 0;
    }
    SocketTool::uninit();
    return iter;
}