//put in queue int packetmgr_put_urge( qqclient* qq, qqpacket* p, int urge ) { qqpacketmgr* mgr = &qq->packetmgr; p->time_alive = time(NULL); p->send_times ++; //ok, send now if( pthread_equal( pthread_self(), mgr->thread_recv ) ){ //recv thread loop_push_to_tail( &mgr->temp_loop, p ); }else{ loop_push_to_tail( &mgr->ready_loop, p ); check_ready_packets( qq ); } return 0; }
int handle_packet( qqclient* qq, qqpacket* p, uchar* data, int len ) { qqpacketmgr* mgr = &qq->packetmgr; mgr->recv_packets ++; bytebuffer* buf; NEW( buf, sizeof( bytebuffer ) ); if( !buf ){ DBG("error: no enough memory to allocate buf."); return -99; } buf->pos = 0; buf->len = buf->size = len; memcpy( buf->data, data, buf->len ); //get packet info if( qq->network == TCP || qq->network == PROXY_HTTP ) get_word( buf ); //packet len p->head = get_byte( buf ); p->tail = buf->data[buf->len-1]; if( p->head != 0x02 || p->tail!=0x03 || buf->len > 2000 ){ DBG("[%u] wrong packet. len=%d head: %d tail: %d", qq->number, buf->len, p->head, p->tail ); DEL( buf ); return -1; } p->version = get_word( buf ); p->command = get_word( buf ); p->seqno = get_word( buf ); uint chk_repeat = (p->seqno<<16)|p->command; //check repeat if( loop_search( &mgr->recv_loop, (void*)chk_repeat, repeat_searcher ) == NULL ){ loop_push_to_tail( &mgr->recv_loop, (void*)chk_repeat ); p->match = match_packet( mgr, p ); p->time_alive = time(NULL); //do a test if ( !p->buf ){ DBG("%u: Error impossible. p->buf: %x p->command: %x", qq->number, p->buf, p->command ); } //deal with the packet process_packet( qq, p, buf ); qqpacket* t; while( (t = loop_pop_from_tail( &mgr->temp_loop )) ){ loop_push_to_head( &mgr->ready_loop, t ); } if( p->match ){ loop_remove( &mgr->sent_loop, p->match ); delete_func( p->match ); } p->match = NULL; mgr->failed_packets = 0; }else{ // DBG("repeated packet: cmd: %x seqno:%x", p->command, p->seqno ); } DEL( buf ); check_ready_packets( qq ); return 0; }
EXPORT user* webqq_create_user( void* session_ptr, uint number, uchar* md5pass ) { user* u; qqclient* qq; u = loop_search( &user_loop, session_ptr, get_user_searcher ); if( u ) return u; NEW( qqclient*, qq, sizeof(qqclient) ); NEW( user*, u, sizeof(user) ); if( !u || !qq ){ DEL( qq ); DEL( u ); return NULL; } u->session_ptr = session_ptr; u->create_time = u->update_time = time(NULL); u->qq = qq; u->reference = 1; qqclient_md5_create( qq, number, md5pass ); qq->auto_accept = 1; //temporarily do this loop_push_to_tail( &user_loop, u ); return u; }
static void check_ready_packets( qqclient* qq ) { qqpacketmgr* mgr = &qq->packetmgr; if( !loop_is_empty(&mgr->sent_loop) || loop_is_empty(&mgr->ready_loop) ) return; //if tcp, we send one by one, otherwise send them all if( loop_is_empty(&mgr->sent_loop) ) //good luck, get a packet and send it. { qqpacket* p = loop_pop_from_head( &mgr->ready_loop ); if( p && p->buf ){ //remove p from ready packets if( p->head!=0x02 || p->tail !=0x03 ){ DBG("Fatal error: p->command=%x p->head: %x p->tail: %x", p->command, p->head, p->tail ); delete_func( p ); return; } int ret = qqsocket_send( qq->socket, p->buf->data, p->buf->len ); // DBG("[%d] out packet cmd: %x", p->command ); if( ret != p->buf->len ){ DBG("send packet failed. ret(%d)!=p->len(%d)", ret, p->buf->len ); delete_func( p ); qqclient_set_process( qq, P_ERROR ); }else{ if( p->need_ack ){ p->time_alive = time(NULL); loop_push_to_tail( &mgr->sent_loop, p ); }else{ delete_func( p ); } } }else{ DBG("no packet. "); } } }