Exemple #1
0
void RUDPSocket::process_fin(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("recv fin from " << remote_addr << ", rudp id = " << rudp_id_);

    RUDP_INFO("send fin2, rudp socket id = " << rudp_id_);
    send_fin2();

    if(state_ == RUDP_CONNECTING || state_ == RUDP_CONNECTED)
    {
        RUDP_INFO("state = RUDP_FIN2_STATE, rudp id = " << rudp_id_);
        set_state(RUDP_FIN2_STATE);

        if(event_handler_ != NULL)
            event_handler_->rudp_close_event(rudp_id_);
        else
        {
            RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
            set_state(RUDP_CLOSE);
        }
    }
    else
    {
        RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
        set_state(RUDP_CLOSE);
    }
    
}
int32_t RUDPObject::create_socket()
{
	int32_t ret = INVALID_RUDP_HANDLE;

	//句柄不够
	if(free_socket_ids_.empty())
		alloc_sockets();

	RUDPHandleSet::iterator it = free_socket_ids_.begin();
	ret = *it;
	if(ret < socket_array_.size() && socket_array_[ret] == NULL)
	{
		RUDPSocket* rudp_session = socket_pool_.pop_obj();
		socket_array_[ret] = rudp_session;

		free_socket_ids_.erase(it);
		used_socket_ids_.insert(ret);
		//关联RUDP SOCKET句柄
		rudp_session->open(ret);

		RUDP_INFO("create rudp socket, socket id = " << ret);
	}
	else
	{
		ret = INVALID_RUDP_HANDLE;
		RUDP_INFO("create rdup failed");
	}

	return ret;
}
Exemple #3
0
void RUDPSocket::process_syn_ack(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("recv syn ack from " << remote_addr << ", rudp id = " << rudp_id_);

    RUDP()->delete_peer_index(remote_rudp_id_, remote_addr_);

    RUDP_INFO("recv syn ack from " << remote_addr);
    if(state_ != RUDP_CONNECTED)
    {
        RUDP_FATAL("state != RUDP_CONNECTED");
        return ;
    }

    PARSE_RUDP_MESSAGE(strm, RUDPSyn2AckPacket, ack, "parse syn_ack failed!");
    //计算RTT
    uint64_t now_ts = CBaseTimeValue::get_time_value().msec();
    uint32_t rtt = static_cast<uint32_t>(now_ts > ack.remote_ts_ ? (now_ts - ack.remote_ts_) : 5);
    ccc_.set_rtt(rtt);

    RUDP_INFO("rtt = " << rtt << ", rudp socket id = " << rudp_id_);

    //触发一个写事件
    if(event_handler_ != NULL)
        event_handler_->rudp_output_event(rudp_id_);
}
Exemple #4
0
int32_t RUDPSocket::handle_timeout(const void *act, uint32_t timer_id)
{
    if(timer_id_ != timer_id)
        return 0;

    timer_id_= 0;

    //解决状态定时的问题,尤其是报文发送
    switch(state_)
    {
    case RUDP_CONNECTING:
        if(send_count_ < SYN_MAX_COUNT)
        {
            send_syn();
            set_timer(CONNECT_DELAY);
            RUDP_DEBUG("resend syn, rudp socket id = " << rudp_id_);
            send_count_ ++;
        }
        else //连接超时
        {
            RUDP_INFO("connecting timeout! state = RUDP_FIN2_STATE, rudp id = " << rudp_id_);
            set_state(RUDP_FIN2_STATE);

            if(event_handler_ != NULL)
                event_handler_->rudp_exception_event(rudp_id_);
            else
            {
                RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
                set_state(RUDP_CLOSE);
            }
        }
        break;

    case RUDP_FIN_STATE:
        if(send_count_ < FIN_MAX_COUNT)
        {
            RUDP_DEBUG("resend fin, rudp socket id = " << rudp_id_);
            send_fin();
            set_timer(ccc_.get_rtt() + TIMER_MIN_DELAY);
            send_count_ ++;
        }
        else
        {
            RUDP_INFO("fin timeout, state = RUDP_CLOSE, rudp id = " << rudp_id_);
            set_state(RUDP_CLOSE);
        }
        break;
    }

    return 0;
}
Exemple #5
0
void RUDPSocket::process_fin2(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("recv fin2 from " << remote_addr << ", rudp id = " << rudp_id_);

    if(event_handler_ != NULL)
    {
        event_handler_->rudp_close_event(rudp_id_);
    }
    else
    {
        RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
        set_state(RUDP_CLOSE);
    }
}
Exemple #6
0
int32_t RUDPSocket::setoption(int32_t op_type, int32_t op_value)
{
    if(rudp_id_ == -1 || state_ > RUDP_FIN_STATE)
    {
        RUDP_FATAL("setoption failed!");

        return -1;
    }

    int32_t ret = 0;
    switch(op_type)
    {
    case RUDP_KEEPLIVE:
        RUDP_INFO("keep live intnal = " << op_value << "ms, rudp socket id = " << rudp_id_);
        keeplive_intnal_ = op_value > DEFAULT_KEEPLIVE ? op_value : DEFAULT_KEEPLIVE;
        break;

    case RUDP_NAGLE:
        if(op_value == 0)
        {
            send_buffer_.set_nagle(false);
            RUDP_INFO("cancel nagle, rudp socket id = " << rudp_id_);
        }
        else
        {
            send_buffer_.set_nagle(true);
            RUDP_INFO("set nagle, rudp socket id = " << rudp_id_);
        }
        break;

    case RUDP_RECV_BUFF_SIZE:
        break;

    case RUDP_SEND_BUFF_SIZE:
        send_buffer_.set_buffer_size(op_value > MIN_SEND_BUFFER_SIZE ? op_value : MIN_SEND_BUFFER_SIZE);
        RUDP_INFO("set send buffer, buffer size = " << op_value);
        break;

    case RUDP_TIMEOUT_COUNT:
        timeout_count_ = op_value > 2 ? op_value : 2;
        RUDP_INFO("set rudp timeout delay = " << timeout_count_ * 6 << "s");
        break;

    default:
        ret = -1;
    }

    return ret;
}
Exemple #7
0
void RUDPCCCObject::on_ack(uint64_t ack_seq)
{
	if(ack_seq <= last_ack_id_)
	{
		return;
	}

	uint32_t space = (uint32_t)(ack_seq - last_ack_id_);
	if(slow_start_) //慢启动窗口决策
	{
		snd_cwnd_ += space;
		if(snd_cwnd_ >= max_cwnd_)
		{
			slow_start_ = false;
			RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_);

			snd_cwnd_ = max_cwnd_;
		}

		RUDP_DEBUG("send window size = " << snd_cwnd_);
	}
	else //平衡状态
	{
		if (recv_count_ / 2 < resend_count_) //出现丢包,不做加速
			loss_flag_ = false;
		else if(resend_count_ == 0) //加速,快速恢复
		{
			snd_cwnd_ = (uint32_t)(snd_cwnd_ + (snd_cwnd_ >> 3));
			snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_);
			loss_flag_ = false;
		}
	}
void RUDPObject::attach(IRUDPAdapter* adapter)
{
	if(adapter == NULL)
	{
		RUDP_WARNING("adapter is NULL");
		return ;
	}

	for(uint8_t i = 0; i < adapter_array_.size(); i ++) //关联本地的网络适配器
	{
		if(adapter_array_[i] == adapter || i >= INVALID_ADAPTER_INDEX) //重复ATTACH
		{
			RUDP_WARNING("repeat attach adapter!!");
			break;
		}

		//绑定
		if(adapter_array_[i] == NULL)
		{
			adapter->set_index(i);
			adapter_array_[i] = adapter;

			RUDP_INFO("attach adapter, id = " << (uint16_t)i << ", local_addr = " << adapter->get_local_addr());
			break;
		}
	}
}
Exemple #9
0
//正常关闭RUDP SOCKET
void RUDPSocket::close()
{
    switch(state_)
    {
    case RUDP_CONNECTING:
    case RUDP_CONNECTED:
        if(event_handler_ != NULL)
        {
            event_handler_->rudp_close_event(rudp_id_);
        }

        //发送SYN
        RUDP_INFO("close rudp socket, state = RUDP_FIN_STATE, rudp id = " << rudp_id_);
        set_state(RUDP_FIN_STATE);
        
        RUDP_DEBUG("send fin, rudp socket id = " << rudp_id_);
        send_fin();
        set_timer(ccc_.get_rtt() + TIMER_MIN_DELAY);

        send_count_ ++;
        break;

    case RUDP_FIN2_STATE:
        set_state(RUDP_CLOSE);
        break;
    }
}
Exemple #10
0
void RUDPCCCObject::on_loss(uint64_t base_seq, const LossIDArray& loss_ids)
{
	if(slow_start_) //取消慢启动
	{
		slow_start_ = false;
		RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_);
	}
}
Exemple #11
0
void RUDPSocket::heartbeat()
{
    if(state_ != RUDP_CONNECTED)
        return ;

    uint64_t now_ts = CBaseTimeValue::get_time_value().msec();

    //心跳计数
    if(now_ts > heart_ts_ + keeplive_intnal_)
    {
        keeplive_count_ ++;
        if(keeplive_count_ > timeout_count_) //超时
        {
            RUDP_ERROR("keep live timeout, rudp socket id = " << rudp_id_);
            if(event_handler_ != NULL) //通知上层异常
            {
                RUDP_INFO("state = RUDP_FIN2_STATE");
                set_state(RUDP_FIN2_STATE);

                event_handler_->rudp_exception_event(rudp_id_);
                return ;
            }
            else
            {
                RUDP_INFO("state = RUDP_CLOSE");
                set_state(RUDP_CLOSE);

                return ;
            }
        }
        else//发送KEEPLIVE
        {
            RUDP_DEBUG("send keeplive, rudp socket id =" << rudp_id_);
            send_keeplive(now_ts);
        }
    }

    //模块心跳
    ccc_.on_timer(now_ts);
    recv_buffer_.on_timer(now_ts, ccc_.get_rtt_var());
    send_buffer_.on_timer(now_ts);
}
Exemple #12
0
void RUDPSocket::process_syn(RUDPSynPacket& syn, const Inet_Addr& remote_addr)
{
    RUDP_INFO("recv syn from " << remote_addr << ", rudp id = " << rudp_id_);

    if(state_ == RUDP_IDLE && rudp_id_ != INVALID_RUDP_HANDLE)
    {
        uint64_t now_timer = CBaseTimeValue::get_time_value().msec();
        //初始化接收SEQ
        recv_buffer_.set_first_seq(syn.start_seq_);
        recv_buffer_.set_send_last_ack_ts(now_timer);

        ccc_.init(send_buffer_.get_buffer_seq() - 1);
        //设置连接信息
        remote_addr_ = remote_addr;
        remote_rudp_id_ = syn.local_rudp_id_;

        RUDP_INFO("sart seq = " << syn.start_seq_ << ", remote_rudp_id = " << remote_rudp_id_);

        RUDP_DEBUG("send syn2, rudp socket id = " << rudp_id_);
        send_syn2(0, syn.local_ts_);

        RUDP_INFO("state = RUDP_CONNECTED, rudp id = " << rudp_id_);
        set_state(RUDP_CONNECTED);

        //发送一个KEEPLIVE
        RUDP_DEBUG("send keeplive, rudp socket id =" << rudp_id_);
        send_keeplive(now_timer);
    }
    else if(state_ == RUDP_CONNECTING || state_ == RUDP_CONNECTED)
    {
        RUDP_INFO("send syn2, rudp socket id = " << rudp_id_);
        send_syn2(0, syn.local_ts_);
    }
    else
    {
        RUDP_DEBUG("send syn2(ERROR_SYN_STATE), rudp socket id = " << rudp_id_);
        send_syn2(ERROR_SYN_STATE, syn.local_ts_);

        RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
        set_state(RUDP_CLOSE);
    }
}
Exemple #13
0
void RUDPSocket::process_keeplive_ack(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("keeplive ack from " << remote_addr << ", rudp id = " << rudp_id_);

    if(state_ != RUDP_CONNECTED)
    {
        RUDP_WARNING("state != RUDP_CONNECTED");
        return ;
    }

    keeplive_count_ = 0;

    PARSE_RUDP_MESSAGE(strm, RDUPKeepLive, ack, "parse keeplive ack failed!");

    //计算RTT
    uint64_t now_ts = CBaseTimeValue::get_time_value().msec();
    uint32_t rtt = static_cast<uint32_t>(now_ts > ack.timestamp_ ? (now_ts - ack.timestamp_) : 5);
    ccc_.set_rtt(rtt);

    RUDP_INFO("rtt = " << rtt << ", rudp socket id = " << rudp_id_);
}
Exemple #14
0
void RUDPSocket::process_syn2(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("recv syn2 from " << remote_addr << ", rudp id = " << rudp_id_);

    PARSE_RUDP_MESSAGE(strm, RUDPSyn2Packet, syn2, "parse syn2 failed!");
    if(state_ == RUDP_CONNECTING)
    {
        if(syn2.syn2_result_ != 0x00) //连接异常
        {
            RUDP_INFO("syn failed! syn2.syn2_result_ = " << (uint16_t)syn2.syn2_result_);

            if(event_handler_ != NULL)
            {
                RUDP_INFO("state = RUDP_FIN2_STATE, rudp id = " << rudp_id_);
                set_state(RUDP_FIN2_STATE);
                event_handler_->rudp_exception_event(rudp_id_);
            }
            else
            {
                RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_);
                set_state(RUDP_CLOSE);
            }

            return ;
        }
        //设置接收BUFF的初始化
        //ccc_.init(syn2.start_seq_ - 1);
        recv_buffer_.set_first_seq(syn2.start_seq_);
        //设置连接信息
        remote_addr_ = remote_addr;
        remote_rudp_id_ = syn2.local_rudp_id_;

        //计算RTT
        uint64_t now_ts = CBaseTimeValue::get_time_value().msec();
        uint32_t rtt = static_cast<uint32_t>(now_ts > syn2.remote_ts_ ? (now_ts - syn2.remote_ts_) : 5);
        recv_buffer_.set_send_last_ack_ts(now_ts);
        ccc_.set_rtt(rtt);

        RUDP_INFO("syn succ, sart seq = " << syn2.start_seq_ << ", remote_rudp_id = " << remote_rudp_id_ << ", rtt = " << rtt);

        RUDP_INFO("state = RUDP_CONNECTED, rudp id = " << rudp_id_);
        set_state(RUDP_CONNECTED);

        RUDP_DEBUG("send syn ack, rudp socket id = " << rudp_id_);
        send_syn_ack(0, syn2.local_ts_);

        //触发一个写事件
        if(event_handler_ != NULL)
            event_handler_->rudp_output_event(rudp_id_);

        heart_ts_ = now_ts;
    }
    else if(state_ == RUDP_CONNECTED)
    {
        RUDP_DEBUG("send syn ack, rudp socket id = " << rudp_id_);
        send_syn_ack(0, syn2.local_ts_);
    }
}
Exemple #15
0
void RUDPSocket::process_keeplive(BinStream& strm, const Inet_Addr& remote_addr)
{
    RUDP_INFO("keeplive from " << remote_addr << ", rudp id = " << rudp_id_);

    if(state_ != RUDP_CONNECTED)
    {
        return ;
    }
    
    keeplive_count_ = 0;

    PARSE_RUDP_MESSAGE(strm, RDUPKeepLive, body, "parse keeplive failed!");

    send_keeplive_ack(body.timestamp_);
}
Exemple #16
0
//强制关闭RUDP SOCKET
void RUDPSocket::force_close()
{
    switch(state_)
    {
    case RUDP_CONNECTING:
    case RUDP_CONNECTED:
        RUDP_DEBUG("send fin, rudp socket id = " << rudp_id_);
        for(uint8_t i = 0; i < 6; i ++) //直接发送3个fin
            send_fin();

    case RUDP_FIN2_STATE:
        RUDP_INFO("state = RUDP_CLOSE");
        set_state(RUDP_CLOSE);
        break;
    }
}
Exemple #17
0
void RUDPCCCObject::on_timer(uint64_t now_ts)
{
	uint32_t delay = core_max(rtt_ / 8, 50);
	if (now_ts >= prev_on_ts_ + delay) //10个RTT决策一次
	{
		print_count_ ++;
		if(print_count_ % 4 == 0)
		{
			RUDP_DEBUG("send window size = " << snd_cwnd_ << ",rtt = " << rtt_ << ",rtt_var = " << rtt_var_ << ",resend = " << resend_count_);
			set_max_cwnd(rtt_);
		}

		if(slow_start_) //停止慢启动过程
		{
			if(print_count_ > 10)
			{
				slow_start_ = false;
				RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_);
			}

		}
		else
		{
			if (recv_count_ > (snd_cwnd_ * delay * 7 / (rtt_ * 8)))
			{
				snd_cwnd_ = (uint32_t)(snd_cwnd_ + core_max(8,(snd_cwnd_ / 8)));
				snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_);
				loss_flag_ = false;
			}
			else if (recv_count_ < snd_cwnd_ * delay * 5 / (rtt_ * 8)){
				snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 16));
				snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_);
				loss_flag_ = true;
			}
			else if (rtt_var_ > 30 && resend_count_ >= core_max(8, snd_cwnd_ * delay * 3 / (8 * rtt_))){
				snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 10));
				snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_);
				loss_flag_ = true;
			}

			resend_count_ = 0;
		}

		recv_count_ = 0;
		prev_on_ts_ = now_ts;
	} 
}
void RUDPObject::free_sockets(int32_t rudp_id)
{
	if(rudp_id > 0 && rudp_id < socket_array_.size() && socket_array_[rudp_id] != NULL)
	{
		RUDPPeerInfo info(socket_array_[rudp_id]->get_remote_rudp_id(), socket_array_[rudp_id]->get_peer_addr());
		peer_socket_ids_.erase(info);

		socket_pool_.push_obj(socket_array_[rudp_id]);
		socket_array_[rudp_id]->reset();
		socket_array_[rudp_id] = NULL;

		free_socket_ids_.insert(rudp_id);
		used_socket_ids_.erase(rudp_id);
	}

	RUDP_INFO("free rudp socket, socket id = " << rudp_id);
}
void RUDPObject::init()
{
	RUDP_INFO("init rudp core!");

	listener_ = NULL;
	free_socket_ids_.clear();
	used_socket_ids_.clear();
	peer_socket_ids_.clear();

	for(int32_t i = 0; i < MAX_LOCAL_ADDR_SIZE; i ++)
	{
		adapter_array_.push_back(NULL);
	}

	alloc_sockets();

	set_timer();
}
Exemple #20
0
int32_t RUDPSocket::send(const uint8_t* data, int32_t data_size)
{
    if(state_ != RUDP_CONNECTED || data_size <= 0)
    {
        RUDP_FATAL("send failed! state_ != RUDP_CONNECTED or data size = 0, rudp id = " << rudp_id_);
        error_code_ = RUDP_SEND_ERROR;
        return -1;
    }

    int32_t ret = send_buffer_.send(data, data_size);
    if(ret <= 0)
    {
        RUDP_INFO("send buffer is full, rudp socket id = " << rudp_id_);
        error_code_ = RUDP_SEND_EAGIN;
    }

    return ret;
}
void RUDPObject::destroy()
{
	cancel_timer();

	int32_t size = socket_array_.size();
	for(int32_t i = 0; i < size; ++i)
	{
		if(socket_array_[i] != NULL)
		{
			socket_array_[i]->force_close();
		}
	}

	free_socket_ids_.clear();
	used_socket_ids_.clear();
	peer_socket_ids_.clear();

	RUDP_INFO("destroy rudp core!");
}
Exemple #22
0
int32_t RUDPSocket::connect(const Inet_Addr& remote_addr)
{
    if(rudp_id_ == INVALID_RUDP_HANDLE || state_ != RUDP_IDLE 
        || local_index_ == 255 || remote_rudp_id_ != INVALID_RUDP_HANDLE)
    {
        RUDP_FATAL("rudp connect failed! rudp socket id = " << rudp_id_);
        error_code_ = RUDP_CONNECT_FAIL;
        return -1;
    }

    remote_addr_ = remote_addr;
    check_sum_ = rand() % 65536; //产生一个会话的CHECK SUM

    RUDP_INFO("state = RUDP_CONNECTING, rudp id = " << rudp_id_ << ", remote addr = " << remote_addr_);
    set_state(RUDP_CONNECTING);

    RUDP_DEBUG("send syn, rudp socket id = " << rudp_id_);
    send_syn();
    ccc_.init(send_buffer_.get_buffer_seq() - 1);
    set_timer(CONNECT_DELAY);
    send_count_ ++;

    return 0;
}
void RUDPObject::process(IRUDPAdapter* adapter, BinStream& strm, const Inet_Addr& remote_addr)
{
	uint8_t index = INVALID_ADAPTER_INDEX; 
	if(adapter != NULL)
		index = adapter->get_index();

	if(adapter_array_[index] == NULL)
	{
		RUDP_FATAL("adapter is not attach!!!");
		return ;
	}

	PARSE_RUDP_HEAD(rudp_head, "parse rudp head failed!!");

	RUDPSocket *rudp_session = get_socket(rudp_head.remote_rudp_id_);
	if(rudp_session != NULL)
	{
		rudp_session->process(rudp_head.msg_id_, rudp_head.check_sum_, strm, remote_addr);
		return ;
	}

	//处理SYN连接请求
	if(rudp_head.msg_id_ == RUDP_SYN && rudp_head.remote_rudp_id_ == INVALID_RUDP_HANDLE)
	{
		PARSE_RUDP_MESSAGE(strm, RUDPSynPacket, syn, "parse syn failed!");

		//在半开连接中找
		rudp_session = find_by_peer_id(syn.local_rudp_id_, remote_addr);
		if(rudp_session == NULL)
		{
			int32_t new_rudp_id = create_socket();
			if(new_rudp_id == INVALID_RUDP_HANDLE)
			{
				send_syn2(rudp_head.remote_rudp_id_, SYSTEM_SYN_ERROR, rudp_head.check_sum_, remote_addr, adapter);
				RUDP_INFO("send syn2 to " << remote_addr);
				return ;
			}

			if(this->bind(new_rudp_id, adapter->get_local_addr()) != 0)
			{
				free_sockets(new_rudp_id);

				send_syn2(rudp_head.remote_rudp_id_, SYSTEM_SYN_ERROR, rudp_head.check_sum_, remote_addr, adapter);
				RUDP_INFO("send syn2 to " << remote_addr);
				return ;
			}

			//建立远程SOCKET ID与本地SOCKET ID的关系,防止重复建立连接
			RUDPPeerInfo info(syn.local_rudp_id_, remote_addr);
			peer_socket_ids_[info] = new_rudp_id;

			rudp_session = get_socket(new_rudp_id);
			rudp_session->set_check_sum(rudp_head.check_sum_);

			//提示上层EVENT HANDLE进行ACCEPT,可以在上层进行SOCKET属性设置
			if(listener_ != NULL)
				listener_->rudp_accept_event(new_rudp_id);
		}

		//进行消息处理
		rudp_session->process_syn(syn, remote_addr);
	}
	else
	{
		RUDP_WARNING("error msg, msg id =  " << (uint16_t)rudp_head.msg_id_ << ", rudp id = " << rudp_head.remote_rudp_id_ << ", remote addr = "<< remote_addr);
	}
}