VOID tunet_stop() { logs_append(g_logs, "TUNET_STOP", NULL, NULL, 0); if(thread_tunet) { logout_socket_buffer = buffer_clear(logout_socket_buffer); tunet_state = TUNET_STATE_LOGOUT; while(tunet_state != TUNET_STATE_NONE && tunet_state != TUNET_STATE_ERROR) os_sleep(20); os_thread_kill(thread_tunet); while(thread_tunet) os_sleep(20); main_socket_buffer = buffer_clear(main_socket_buffer); keepalive_socket_buffer = buffer_clear(keepalive_socket_buffer); logout_socket_buffer = buffer_clear(logout_socket_buffer); strcpy(keepalive_server, ""); keepalive_server_port = 0; strcpy(msg_server, ""); msg_server_port = 0; } logs_append(g_logs, "TUNET_STOP", "END", NULL, 0); }
VOID dot1x_start(USERCONFIG *uc) { assert(uc != NULL); ethcard_stop_loop_recv(); if(ethcard) ethcard = ethcard_close(ethcard); dot1x_state = DOT1X_STATE_NONE; os_tick_clear(tick_timeout); logs_append(g_logs, "DOT1X_START", NULL, NULL, 0); memcpy(&userconfig, uc, sizeof(USERCONFIG)); if((ethcard = ethcard_open(userconfig.szAdaptor)) == NULL) { logs_append(g_logs, "DOT1X_START_FAIL", "ETHCARD_OPEN", NULL, 0); dot1x_state = DOT1X_STATE_ERROR; //dprintf("failed to open the ethcard!\n"); return; } ethcard_start_loop_recv(ethcard, dot1x_loop_recv_proc); dot1x_state = DOT1X_STATE_LOGIN; dot1x_logon_request(); }
static int tunet_logon_send_tunet_user() { BUFFER *buf; BYTE tmpbuf[100]; int len; UINT32 lang; BOOL sr, sw, se; if(!main_socket) return OK; os_socket_tcp_status(main_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_LOGIN) return OK; if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "SEND_TUNET_USER", NULL, 0); return ERR; } if(!sw) return OK; buf = buffer_new(200); //hex2buf("12 54 55 4e 45 54 20 55 53 45 52 00 00 4e ea 00 00 00 01", tmpbuf, &len); // 00 for english //buf = buffer_append(buf, tmpbuf, len); hex2buf("12 54 55 4e 45 54 20 55 53 45 52 00 00 4e ea", tmpbuf, &len); buf = buffer_append(buf, tmpbuf, len); lang = htonl(userconfig.language); buf = buffer_append(buf, (BYTE *)(&lang), 4); os_socket_tcp_send(main_socket, buf->data, buf->len); tunet_state = TUNET_STATE_RECV_WELCOME; logs_append(g_logs, "TUNET_LOGON_SEND_TUNET_USER", NULL, buf->data, buf->len); //dprintf("已经向主服务器发出登陆请求...\n"); buf = buffer_free(buf); return OK; }
VOID tunet_start(USERCONFIG *uc) { assert(uc != NULL); if(thread_tunet) { os_thread_kill(thread_tunet); while(thread_tunet) os_sleep(20); } logs_append(g_logs, "TUNET_START", NULL, NULL, 0); memcpy(&userconfig, uc, sizeof(USERCONFIG)); strcpy(keepalive_server, ""); keepalive_server_port = 0; strcpy(msg_server, ""); msg_server_port = 0; main_socket = os_socket_tcp_close(main_socket); keepalive_socket = os_socket_tcp_close(keepalive_socket); logout_socket = os_socket_tcp_close(logout_socket); tunet_state = TUNET_STATE_LOGIN; main_socket_buffer = buffer_clear(main_socket_buffer); keepalive_socket_buffer = buffer_clear(keepalive_socket_buffer); logout_socket_buffer = buffer_clear(logout_socket_buffer); thread_tunet = os_thread_create(tunet_thread, NULL, FALSE, FALSE); }
VOID dot1x_stop() { if(dot1x_state != DOT1X_STATE_NONE) { dot1x_state = DOT1X_STATE_LOGOUT; logs_append(g_logs, "DOT1X_STOP", NULL, NULL, 0); dot1x_logout(); } }
VOID tunet_reset() { logs_append(g_logs, "TUNET_RESET", NULL, NULL, 0); if(thread_tunet) { os_thread_kill(thread_tunet); while(thread_tunet) os_sleep(20); } tunet_state = TUNET_STATE_NONE; }
static void dot1x_logon_send_username(int id) { BUFFER *buf; BYTE tmpbuf[100]; EAPOL_PACKET_HEADER *pkt; STRING *strUserAtIp = NULL; buf = buffer_new(sizeof(EAPOL_PACKET_HEADER)); pkt = (EAPOL_PACKET_HEADER *)buf->data; memcpy(pkt->dest, hex2buf(DOT1XMAC, tmpbuf, NULL), 6); memcpy(pkt->src, hex2buf(userconfig.szMac, tmpbuf, NULL), 6); pkt->tags[0] = 0x88; pkt->tags[1] = 0x8e; pkt->eapol_version = 1; pkt->eapol_type = EAPOL_PACKET; strUserAtIp = string_append(strUserAtIp, userconfig.szUsername); strUserAtIp = string_append(strUserAtIp, "@"); strUserAtIp = string_append(strUserAtIp, userconfig.szIp); pkt->eapol_length = htons((u_short)(strlen(strUserAtIp->str) + 5)); pkt->code = EAP_RESPONSE; pkt->identifier = id; pkt->length = pkt->eapol_length; pkt->type = EAP_TYPE_ID; buf->len = sizeof(EAPOL_PACKET_HEADER); buf = buffer_append(buf, (BYTE *)strUserAtIp->str, strlen(strUserAtIp->str)); if(buf->len < 60) buf = buffer_append(buf, null_buffer_60, 60 - buf->len); ethcard_send_packet(ethcard, buf->data, buf->len); logs_append(g_logs, "DOT1X_LOGON_SEND_USERNAME", NULL, buf->data, buf->len); //if(ethcard_send_packet(ethcard, buf->data, buf->len) != 0) //{ // dprintf("Error with WinPCap\n"); //} strUserAtIp = string_free(strUserAtIp); buf = buffer_free(buf); }
static int tunet_logout_send_logout() { BOOL sr, sw, se; BYTE tmpbuf[1024]; BUFFER *buf = NULL; INT len; if(!logout_socket) return OK; os_socket_tcp_status(logout_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_LOGOUT) return OK; // printf("sending logout info.\n"); if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "SEND_LOGOUT", NULL, 0); return ERR; } if(!sw) return OK; hex2buf("0f 54 55 4e 45 54 20 55 53 45 52", tmpbuf, &len); buf = buffer_append(buf, tmpbuf, len); os_socket_tcp_send(logout_socket, buf->data, buf->len); tunet_state = TUNET_STATE_LOGOUT_RECV_LOGOUT; logs_append(g_logs, "TUNET_LOGON_SEND_LOGOUT", NULL, buf->data, buf->len); //dprintf("向主服务器发出注销请求...\n"); buf = buffer_free(buf); return OK; }
static void dot1x_logon_request() { BUFFER *buf; BYTE tmpbuf[100]; buf = buffer_new(200); buf = buffer_append(buf, hex2buf(DOT1XMAC, tmpbuf, NULL), 6); buf = buffer_append(buf, hex2buf(userconfig.szMac, tmpbuf, NULL), 6); buf = buffer_append(buf, hex2buf((CHAR *)"88 8e", tmpbuf, NULL), 2); buf = buffer_append(buf, hex2buf((CHAR *)"01 01 00 00", tmpbuf, NULL), 4); if(buf->len < 60) buf = buffer_append(buf, null_buffer_60, 60 - buf->len); ethcard_send_packet(ethcard, buf->data, buf->len); logs_append(g_logs, "DOT1X_LOGON_REQUEST", NULL, buf->data, buf->len); buf = buffer_free(buf); }
VOID dot1x_reset() { dot1x_state = DOT1X_STATE_NONE; logs_append(g_logs, "DOT1X_RESET", NULL, NULL, 0); }
static int tunet_logon_recv_welcome() { BYTE tmpbuf[1024 * 8]; CHAR tmp[1024]; BYTE btag; UINT32 unknowntag; UINT32 datalen; BYTE *p; int len; const CHAR *WELCOME = "WELCOME TO TUNET"; //int msglen = 0; STRING *str = NULL; // BOOL sr, sw, se; if(!main_socket) return OK; // os_socket_tcp_status(main_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_RECV_WELCOME) return OK; /* if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_WELCOME", NULL, 0); return ERR; } if(!sr) return OK; */ len = os_socket_tcp_recv(main_socket, tmpbuf, sizeof(tmpbuf)); if(len == -1) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_WELCOME", NULL, 0); return ERR; } if(len > 0) { main_socket_buffer = buffer_append(main_socket_buffer, tmpbuf, len); logs_append(g_logs, "TUNET_LOGON_RECV", "WELCOME", tmpbuf, len); buf2output(tmpbuf, len, tmp, 16); //dprintf("data received(recv welcome):\n%s\n", tmp); p = main_socket_buffer->data; while(buffer_fetch_BYTE(main_socket_buffer, &p, &btag)) { switch(btag) { case 0x01: if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, strlen(WELCOME))) return OK; if(strncmp(str->str, WELCOME, strlen(WELCOME)) != 0) { str = string_free(str); //TODO //process such error!!!!!!!!! logs_append(g_logs, "TUNET_LOGON_WELCOME", str->str, NULL, 0); tunet_state = TUNET_STATE_ERROR; return OK; } str = string_free(str); if(!buffer_fetch_DWORD(main_socket_buffer, &p, &unknowntag)) return OK; unknowntag = htonl(unknowntag); if(!buffer_fetch_bytes(main_socket_buffer, &p, welcome_data, 8)) return OK; if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); //dprintf("欢迎消息长 %d\n", datalen); if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen)) return OK; logs_append(g_logs, "TUNET_LOGON_WELCOME", str->str, NULL, 0); //dprintf("%s\n", str->str); str = string_free(str); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; tunet_state = TUNET_STATE_REPLY_WELCOME; break; case 0x02: case 0x05: datalen = htonl(BUF_FETCH_DWORD(p)); //dprintf("出错消息长 %d\n", datalen); str = string_new(""); str = string_nappend(str, (CHAR *)p, datalen); //dprintf("%s\n", str->str); tunet_state = TUNET_STATE_ERROR; logs_append(g_logs, "TUNET_LOGON_ERROR", str->str, NULL, 0); str = string_free(str); BUF_ROLL(p, datalen); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; } } } return OK; }
static int tunet_logon_reply_welcome() { BUFFER *buf; BYTE des3data[12]; des3_context ctx3; UINT32 limitation; // BOOL sr, sw, se; if(!main_socket) return OK; // os_socket_tcp_status(main_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_REPLY_WELCOME) return OK; /* if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "REPLY_WELCOME", NULL, 0); return ERR; } if(!sw) return OK; */ memset(des3data, 0, sizeof(des3data)); des3_set_3keys( &ctx3, userconfig.md5Password, userconfig.md5Password + 8, userconfig.md5Password ); des3_encrypt( &ctx3, (uint8 *)welcome_data, (uint8 *)des3data); buf = buffer_new(100); buf = buffer_append(buf, (BYTE *)"\x03", 1); buf = buffer_append(buf, userconfig.md5Username, 16); buf = buffer_append(buf, des3data, 8); limitation = htonl(userconfig.limitation); buf = buffer_append(buf, (BYTE *)&limitation, 4); os_socket_tcp_send(main_socket, buf->data, buf->len); tunet_state = TUNET_STATE_RECV_REMAINING_DATA; logs_append(g_logs, "TUNET_LOGON_REPLY_WELCOME", NULL, buf->data, buf->len); //dprintf("%s\n", "已经应答welcome的数据包。准备接受剩余数据..."); buf = buffer_free(buf); return OK; }
static VOID dot1x_loop_recv_proc(ETHCARD *ethcard, BYTE *pkt_data, INT pkt_len) { BYTE tmpbuf[100]; EAPOL_RANDSTREAM_PACKET * stmpkt = (EAPOL_RANDSTREAM_PACKET *)pkt_data; EAPOL_PACKET_HEADER *pkthdr = (EAPOL_PACKET_HEADER *)pkt_data; /* INT i,j; dprintf("dot1x_loop_recv_proc\n"); for (i=0; i<pkt_len; i++) dprintf("%.2x ", pkt_data[i]); dprintf("Recv: \n DEST: "); for(i = 1, j = 0; j < 6; i++,j++) { dprintf("%.2x ", pkt_data[i-1]); } dprintf("\nSRC : "); for(j = 0; j < 6; i++,j++) { dprintf("%.2x ", pkt_data[i-1]); } i += 2; //0x888E dprintf("\nDATA:\n"); for (j =1 ; (i < pkt_len ) ; i++, j++) { dprintf("%.2x ", pkt_data[i-1]); if ( (j % 16) == 0) dprintf("\n"); } dprintf("\n"); */ #define FNAME "dot1x_loop_recv_proc" if (!pkt_data) dprintf(FNAME": !pkt_data error\n"); if (!pkt_len) dprintf(FNAME": !pkt_len error\n"); if (memcmp(pkthdr->dest, hex2buf(userconfig.szMac, tmpbuf, NULL), 6) != 0) { hex2buf(DOT1XMAC, tmpbuf, NULL); if (memcmp(pkthdr->dest, tmpbuf, 6) != 0) { char tempbuf[100]; dprintf(FNAME": Not our packet\n"); buf2hex(pkthdr->dest, 6, tempbuf); dprintf(FNAME": packet dest: %s\n", tempbuf); dprintf(FNAME": our addr: %s\n", userconfig.szMac); } } if (pkthdr->tag != 0x8e88) dprintf(FNAME": proto error : %x\n", pkthdr->tag); #undef FNAME if(pkt_data && pkt_len && memcmp(pkthdr->dest, hex2buf(userconfig.szMac, tmpbuf, NULL), 6) == 0 && (pkthdr->tag == 0x8e88)) { logs_append(g_logs, "DOT1X_RECV", NULL, pkt_data, pkt_len); os_tick_clear(tick_timeout); switch (pkthdr->eapol_type) { case EAP_PACK_TYPE: //dprintf("EAP_PACK_TYPE receiveID = %d code = %d\n", pkthdr->identifier, pkthdr->code); switch (pkthdr->code) { case EAP_REQUEST: switch(pkthdr->type) { case EAP_TYPE_ID: logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_REQUEST", NULL, 0); dot1x_state = DOT1X_STATE_RESPONSE; dot1x_logon_send_username(pkthdr->identifier); break; case EAP_TYPE_MD5: if(sizeof(EAPOL_PACKET_HEADER) + sizeof(stmpkt->streamlen) + stmpkt->streamlen <= (UINT32)pkt_len) { logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_REQUEST(AUTH)", NULL, 0); dot1x_state = DOT1X_STATE_AUTH; dot1x_logon_auth(pkthdr->identifier, stmpkt->stream, stmpkt->streamlen); } else { dot1x_state = DOT1X_STATE_LOGIN; dot1x_logon_request(); } break; } //dprintf(" EAP_REQUEST\n"); /* if( dot1x_state == DOT1X_STATE_LOGIN || dot1x_state == DOT1X_STATE_SUCCESS || dot1x_state == DOT1X_STATE_FAILURE) { logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_REQUEST", NULL, 0); dot1x_state = DOT1X_STATE_RESPONSE; dot1x_logon_send_username(pkthdr->identifier); } else if(dot1x_state == DOT1X_STATE_RESPONSE) { //dprintf(" streamlen = %d\n", stmpkt->streamlen); if(sizeof(EAPOL_PACKET_HEADER) + sizeof(stmpkt->streamlen) + stmpkt->streamlen <= (UINT32)pkt_len) { logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_REQUEST(AUTH)", NULL, 0); dot1x_state = DOT1X_STATE_AUTH; dot1x_logon_auth(pkthdr->identifier, stmpkt->stream, stmpkt->streamlen); } else { //dprintf(" ERROR WHEN RECV STREAM !! Retry ...\n"); dot1x_state = DOT1X_STATE_LOGIN; dot1x_logon_request(); } } */ break; case EAP_RESPONSE: logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_RESPONSE", NULL, 0); //dprintf(" EAP_RESPONSE\n"); break; case EAP_SUCCESS: logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_SUCCESS", NULL, 0); //dprintf(" EAP_SUCCESS\n"); dot1x_state = DOT1X_STATE_SUCCESS; break; case EAP_FAILURE: //TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!! if(dot1x_state == DOT1X_STATE_LOGOUT) { logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_FAILURE(LOGOUT)", NULL, 0); //dprintf(" EAP_FAILURE(LOGOUT)\n"); dot1x_state = DOT1X_STATE_NONE; //Here, we finished stopping DOT1X !!!! logs_append(g_logs, "DOT1X_STOP", "END", NULL, 0); break; } else { logs_append(g_logs, "DOT1X_RECV_PACK", "EAP_FAILURE", NULL, 0); //dprintf(" EAP_FAILURE\n"); dot1x_state = DOT1X_STATE_FAILURE; if(userconfig.bRetryDot1x) { // keep retrying ... dot1x_logon_request(); } } break; default: logs_append(g_logs, "DOT1X_RECV_PACK", "UNKNOWN", NULL, 0); //dprintf(" Unknown EAP_TYPE\n"); } break; case EAPOL_START: logs_append(g_logs, "DOT1X_RECV_START", NULL, NULL, 0); //dprintf("EAPOL_START\n"); break; case EAPOL_LOGOFF: logs_append(g_logs, "DOT1X_RECV_LOGOFF", NULL, NULL, 0); //dprintf("EAPOL_LOGOFF\n"); break; case EAPOL_KEY: logs_append(g_logs, "DOT1X_RECV_KEY", NULL, NULL, 0); //dprintf("EAPOL_KEY\n"); break; case EAPOL_ASF_ALERT: logs_append(g_logs, "DOT1X_RECV_ASF_ALERT", NULL, NULL, 0); //dprintf("EAPOL_ASF_ALERT\n"); break; default: logs_append(g_logs, "DOT1X_RECV_UNKNOWN", NULL, NULL, 0); return; } //dprintf("\n\n"); } else { //it's not the packet for us } }
static void dot1x_logon_auth(int id, BYTE *stream, int streamlen) { BUFFER *buf = buffer_new(1024); EAPOL_PACKET_HEADER *pkt; BYTE md5_result[16]; BYTE tmpbuf[100]; STRING *strUserAtIp = NULL; buf = buffer_append(buf, (BYTE *)"?", 1); buf->data[0] = id; buf = buffer_append(buf, (BYTE *)userconfig.szMD5Password, strlen(userconfig.szMD5Password)); buf = buffer_append(buf, stream, streamlen); MD5Buffer(buf->data, buf->len, md5_result); buf = buffer_free(buf); buf = buffer_new(sizeof(EAPOL_PACKET_HEADER)); pkt = (EAPOL_PACKET_HEADER *)buf->data; memcpy(pkt->dest, hex2buf(DOT1XMAC, tmpbuf, NULL), 6); memcpy(pkt->src, hex2buf(userconfig.szMac, tmpbuf, NULL), 6); pkt->tags[0] = 0x88; pkt->tags[1] = 0x8e; pkt->eapol_version = 1; pkt->eapol_type = EAPOL_PACKET; strUserAtIp = string_append(strUserAtIp, userconfig.szUsername); strUserAtIp = string_append(strUserAtIp, "@"); strUserAtIp = string_append(strUserAtIp, userconfig.szIp); pkt->eapol_length = htons((u_short)(strlen(strUserAtIp->str) + 16/*md5*/ + 6)); pkt->code = EAP_RESPONSE; pkt->identifier = id; pkt->length = pkt->eapol_length; pkt->type = EAP_TYPE_MD5; buf->len = sizeof(EAPOL_PACKET_HEADER); buf = buffer_append(buf, (BYTE *)"\x10", 1); buf = buffer_append(buf, md5_result, 16); buf = buffer_append(buf, (BYTE *)strUserAtIp->str, strlen(strUserAtIp->str)); if(buf->len < 60) buf = buffer_append(buf, null_buffer_60, 60 - buf->len); ethcard_send_packet(ethcard, buf->data, buf->len); logs_append(g_logs, "DOT1X_LOGON_AUTH", NULL, buf->data, buf->len); /* if(ethcard_send_packet(ethcard, buf->data, buf->len) != 0) { dprintf("Error with WinPCap\n"); } */ strUserAtIp = string_free(strUserAtIp); buf = buffer_free(buf); }
static int tunet_logon_recv_remaining_data() { BYTE tmpbuf[1024 * 8]; CHAR tmp[1024]; CHAR sztmp[255]; BYTE *p; INT len; BYTE key77[8]; STRING *str = NULL; char des3data[12]; des3_context ctx3; TIME tm; UINT32 datalen, port; UINT32 uint_money; BYTE btag; // BOOL sr, sw, se; if(!main_socket) return OK; // printf("tunet_logon_recv_remaining_data() called.\n"); // os_socket_tcp_status(main_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_RECV_REMAINING_DATA && tunet_state != TUNET_STATE_KEEPALIVE) return OK; /* if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_REMAINING_DATA", NULL, 0); return ERR; } if(!sr) return OK; */ len = os_socket_tcp_recv(main_socket, tmpbuf, sizeof(tmpbuf)); if(len == -1) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_REMAINING_DATA", NULL, 0); return ERR; } if(len > 0) { main_socket_buffer = buffer_append(main_socket_buffer, tmpbuf, len); logs_append(g_logs, "TUNET_LOGON_RECV", "REMAINING", tmpbuf, len); buf2output(tmpbuf, len, tmp, 16); //dprintf("data received(recv remaining):\n%s\n", tmp); p = main_socket_buffer->data; while(buffer_fetch_BYTE(main_socket_buffer, &p, &btag)) { switch(btag) { case 0x01: if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); memset(keepalive_server, 0, sizeof(keepalive_server)); if(!buffer_fetch_bytes(main_socket_buffer, &p, (BYTE *)keepalive_server, datalen)) return OK; if(!buffer_fetch_DWORD(main_socket_buffer, &p, &port)) return OK; port = htonl(port); keepalive_server_port = (short)port; snprintf(sztmp, sizeof(sztmp), "%s:%d", keepalive_server, keepalive_server_port); //dprintf("保持活动服务器:%s\n", sztmp); //we got the KEEPALIVE server, try to keep alive os_tick_clear(keepalive_timeout); tunet_state = TUNET_STATE_KEEPALIVE; logs_append(g_logs, "TUNET_LOGON_KEEPALIVE_SERVER", sztmp, NULL, 0); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; case 0x02: //出错消息 if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); //dprintf("出错消息长 %d\n", datalen); if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen)) return OK; //dprintf("%s\n", str->str); tunet_state = TUNET_STATE_ERROR; logs_append(g_logs, "TUNET_LOGON_ERROR", str->str, NULL, 0); str = string_free(str); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; case 0x05: if(buffer_fetch_BYTE(main_socket_buffer, &p, &btag)) { if(btag != 0) { //dprintf("与消息中介服务器通信结束。\n"); main_socket = os_socket_tcp_close(main_socket); logs_append(g_logs, "TUNET_LOGON_FINISH_MSGSERVER", NULL, NULL, 0); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; } } BUF_ROLL(p, -1); //restore the point for further use //出错消息 if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); //dprintf("出错消息长 %d\n", datalen); if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen)) return OK; //dprintf("%s\n", str->str); tunet_state = TUNET_STATE_ERROR; logs_append(g_logs, "TUNET_LOGON_ERROR", str->str, NULL, 0); str = string_free(str); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; case 0x04: case 0x08: if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); memset(msg_server, 0, sizeof(msg_server)); if(!buffer_fetch_bytes(main_socket_buffer, &p, (BYTE *)msg_server, datalen)) return OK; if(!buffer_fetch_DWORD(main_socket_buffer, &p, &port)) return OK; port = htonl(port); msg_server_port = (short)port; if(!buffer_fetch_bytes(main_socket_buffer, &p, key77, 8)) return OK; //登陆消息 if(!buffer_fetch_DWORD(main_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); //dprintf("登陆消息长 %d\n", datalen); if(!buffer_fetch_STRING(main_socket_buffer, &p, &str, datalen)) return OK; //dprintf("%s\n", str->str); logs_append(g_logs, "TUNET_LOGON_MSG", str->str, NULL, 0); str = string_free(str); //make a new key for keep-alive //dprintf("key77 == %s\n", buf2hex(key77, 8, tmp)); memset(des3data, 0, sizeof(des3data)); des3_set_3keys( &ctx3, userconfig.md5Password, userconfig.md5Password + 8, userconfig.md5Password ); des3_encrypt( &ctx3, (uint8 *)key77, (uint8 *)des3data); memcpy(keepalive_key, des3data, 8); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; //-------------------------------- snprintf(sztmp, sizeof(sztmp), "%s:%d", msg_server, msg_server_port); //dprintf("准备连接到消息中介服务器 %s 获得活动服务器地址....\n", sztmp); logs_append(g_logs, "TUNET_LOGON_MSGSERVER", sztmp, NULL, 0); main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; //switch to another server to get alive-server ip strcpy(keepalive_server, ""); main_socket = os_socket_tcp_close(main_socket); main_socket = os_socket_tcp_connect(msg_server, msg_server_port, FALSE); break; case 0x1b: if(!buffer_fetch_DWORD(main_socket_buffer, &p, &uint_money)) return OK; uint_money = htonl(uint_money); snprintf(sztmp, sizeof(sztmp), "%0.2f", tunet_imoney_to_fmoney(uint_money)); //dprintf("您在登陆前的余额是:%s\n", sztmp); logs_append(g_logs, "TUNET_LOGON_MONEY", sztmp, NULL, 0); if(buffer_has_data(main_socket_buffer, p, 16)) { snprintf(sztmp, sizeof(sztmp), "%d.%d.%d.%d/%d.%d.%d.%d", p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); logs_append(g_logs, "TUNET_LOGON_IPs", sztmp, NULL, 0); //dprintf("登陆IP状况: %s\n", sztmp); BUF_ROLL(p, 8); tm = os_time_convert(htonl(BUFDWORD(p))); snprintf(sztmp, sizeof(sztmp), "%d-%d-%d %d:%d:%d", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second ); logs_append(g_logs, "TUNET_LOGON_SERVERTIME", sztmp, NULL, 0); //dprintf("当前服务器时间: %s\n", sztmp); BUF_ROLL(p, 4); tm = os_time_convert(htonl(BUFDWORD(p))); snprintf(sztmp, sizeof(sztmp), "%d-%d-%d %d:%d:%d", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second ); logs_append(g_logs, "TUNET_LOGON_LASTTIME", sztmp, NULL, 0); //dprintf("上次登陆时间: %s\n", sztmp); BUF_ROLL(p, 4); } else { return OK; } main_socket_buffer = buffer_rollto(main_socket_buffer, p); p = main_socket_buffer->data; break; } } } return OK; }
THREADRET tunet_thread(THREAD *self) { BOOL hasErr = FALSE; fd_set rset; fd_set wset; fd_set eset; struct timeval tv; time_t keepalive_watchDog=0; tv.tv_sec=2; tv.tv_usec=0; int ret,flags; int maxsock; int main_retry=0; char flag,connected=0; logs_append(g_logs, "TUNET_THREAD_STARTING", NULL, NULL, 0); while(os_thread_is_running(self) || os_thread_is_paused(self)) { // printf("main_socket=%d\n",main_socket); if (keepalive_watchDog) { if (time(NULL)-keepalive_watchDog>=36) { if(tunet_keepalive()==ERR) break; } } if (tunet_state==TUNET_STATE_RECV_REMAINING_DATA || tunet_state==TUNET_STATE_RECV_WELCOME) { keepalive_watchDog=time(NULL); } hasErr=FALSE; if(tunet_get_state() == TUNET_STATE_NONE) { break; } if(tunet_get_state() == TUNET_STATE_ERROR) { //an server-side error occurs when trying to login/logout logs_append(g_logs, "TUNET_ERROR", NULL, NULL, 0); break; } if (tunet_state ==TUNET_STATE_LOGOUT) { if (!connected) { break; } tunet_connect_logout_server(); } if (tunet_state==TUNET_STATE_LOGOUT||tunet_state==TUNET_STATE_LOGOUT_RECV_LOGOUT) { hasErr |= (tunet_logout_send_logout() == ERR); hasErr |= (tunet_logout_recv_logout() == ERR); if(hasErr) { //if an error occurs when LOGOUT, we can just omit it, and exit the thread. break; } os_thread_test_paused(self); os_sleep(20); }else { if(tunet_state == TUNET_STATE_LOGIN){ tunet_connect_main_server(); } if(tunet_connect_keepalive_server()==ERR){ break; } if (tunet_state == TUNET_STATE_KEEPALIVE||tunet_state==TUNET_STATE_RECV_REMAINING_DATA) { connected=1; } FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset); maxsock=0; flag=0; if (main_socket) { FD_SET(main_socket, &rset); FD_SET(main_socket, &wset); FD_SET(main_socket, &eset); if (main_socket>=maxsock) { maxsock=main_socket; } flag=1; } if (keepalive_socket) { FD_SET(keepalive_socket,&rset); FD_SET(keepalive_socket,&eset); if (keepalive_socket>=maxsock) { maxsock=keepalive_socket; } } ret=select(maxsock+1,&rset,&wset,&eset,&tv); if (ret<0) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "UNKNOWN", NULL, 0); break; }else if (ret==0) { if (tunet_state==TUNET_STATE_LOGIN) { if (main_retry>=3) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "MAIN", NULL, 0); break; } main_retry++; } os_thread_test_paused(self); continue; } if (flag) { if (FD_ISSET(main_socket,&wset)) { tunet_logon_send_tunet_user(); tunet_logon_reply_welcome(); } if (FD_ISSET(main_socket,&rset)) { if(tunet_logon_recv_welcome()==ERR){ logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_WELCOME", NULL, 0); break; } if(tunet_logon_recv_remaining_data()==ERR){ logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_REMAINING_DATA", NULL, 0); break; } } if (FD_ISSET(main_socket, &eset)) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "MAIN", NULL, 0); break; } } if (FD_ISSET(keepalive_socket,&rset)) { if(tunet_keepalive()==ERR){ logs_append(g_logs, "TUNET_NETWORK_ERROR", "KEEPALIVE", NULL, 0); break; } keepalive_watchDog=time(NULL); } if (FD_ISSET(keepalive_socket, &eset)) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "KEEPALIVE", NULL, 0); break; } os_thread_test_paused(self); } } main_socket = os_socket_tcp_close(main_socket); keepalive_socket = os_socket_tcp_close(keepalive_socket); logout_socket = os_socket_tcp_close(logout_socket); main_socket_buffer = buffer_clear(main_socket_buffer); keepalive_socket_buffer = buffer_clear(keepalive_socket_buffer); logout_socket_buffer = buffer_clear(logout_socket_buffer); tunet_state = TUNET_STATE_NONE; logs_append(g_logs, "TUNET_THREAD_EXITING", NULL, NULL, 0); thread_tunet = os_thread_free(thread_tunet); return 0; }
THREADRET tunet_thread(THREAD *self) { BOOL hasErr = FALSE; logs_append(g_logs, "TUNET_THREAD_STARTING", NULL, NULL, 0); while(os_thread_is_running(self) || os_thread_is_paused(self)) { if(tunet_state == TUNET_STATE_LOGIN) tunet_connect_main_server(); hasErr = FALSE; hasErr |= (tunet_logon_send_tunet_user() == ERR); hasErr |= (tunet_logon_recv_welcome() == ERR); hasErr |= (tunet_logon_reply_welcome() == ERR); hasErr |= (tunet_logon_recv_remaining_data() == ERR); hasErr |= (tunet_connect_keepalive_server() == ERR); hasErr |= (tunet_keepalive() == ERR); if(hasErr) { /* COMMENT: We won't help the user to retry for some network error shoud be dealt by the users. //a network error occurs when try to LOGIN main_socket = os_socket_tcp_close(main_socket); keepalive_socket = os_socket_tcp_close(keepalive_socket); tunet_state = TUNET_STATE_LOGIN; continue; */ break; } hasErr = FALSE; if(tunet_state == TUNET_STATE_LOGOUT) tunet_connect_logout_server(); hasErr |= (tunet_logout_send_logout() == ERR); hasErr |= (tunet_logout_recv_logout() == ERR); if(hasErr) { //if an error occurs when LOGOUT, we can just omit it, and exit the thread. break; } if(tunet_get_state() == TUNET_STATE_NONE) { //nothing to do , exit the thread break; } if(tunet_get_state() == TUNET_STATE_ERROR) { //an server-side error occurs when trying to login/logout logs_append(g_logs, "TUNET_ERROR", NULL, NULL, 0); break; } os_thread_test_paused(self); os_sleep(20); } main_socket = os_socket_tcp_close(main_socket); keepalive_socket = os_socket_tcp_close(keepalive_socket); logout_socket = os_socket_tcp_close(logout_socket); main_socket_buffer = buffer_clear(main_socket_buffer); keepalive_socket_buffer = buffer_clear(keepalive_socket_buffer); logout_socket_buffer = buffer_clear(logout_socket_buffer); tunet_state = TUNET_STATE_NONE; logs_append(g_logs, "TUNET_THREAD_EXITING", NULL, NULL, 0); thread_tunet = os_thread_free(thread_tunet); return 0; }
int tunet_keepalive() { BYTE tmpbuf[1024]; BYTE repbuf[9]; CHAR tmp[1024]; BYTE *p; BYTE btag; BYTE data[16]; CHAR smoney[255]; des_context ctx; int len; UINT32 uint_used_money, uint_money; STRING *str = NULL; // BOOL sr, sw, se; if(!keepalive_socket) return OK; // os_socket_tcp_status(keepalive_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_KEEPALIVE){ // printf("state error\n"); return OK; } /* if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "KEEPALIVE", NULL, 0); return ERR; } if(!sr) return OK; */ // printf("start recv.\n"); len = os_socket_tcp_recv(keepalive_socket, tmpbuf, sizeof(tmpbuf)); // printf("finished recv.\n"); if(len == -1) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "KEEPALIVE", NULL, 0); return ERR; } if(len > 0) { keepalive_socket_buffer = buffer_append(keepalive_socket_buffer, tmpbuf, len); buf2output(tmpbuf, len, tmp, 16); //dprintf("data received(keepalive):\n%s\n", tmp); logs_append(g_logs, "TUNET_KEEPALIVE_RECV", NULL, tmpbuf, len); p = keepalive_socket_buffer->data; while(buffer_fetch_BYTE(keepalive_socket_buffer, &p, &btag)) { switch(btag) { case 0x03: if(!buffer_fetch_bytes(keepalive_socket_buffer, &p, data, 16)) return OK; logs_append(g_logs, "TUNET_KEEPALIVE_CONFIRM", NULL, NULL, 0); uint_used_money = htonl(BUFDWORD( (data + 8) )); uint_money = htonl(BUFDWORD( (data + 12) )); des_set_key(&ctx, (uint8 *)keepalive_key); des_encrypt(&ctx, (uint8 *)data, (uint8 *)(repbuf + 1)); repbuf[0] = 0x02; os_socket_tcp_send(keepalive_socket, repbuf, sizeof(repbuf)); keepalive_socket_buffer = buffer_rollto(keepalive_socket_buffer, p); p = keepalive_socket_buffer->data; os_tick_clear(keepalive_timeout); snprintf(smoney, sizeof(smoney), "%0.2f", tunet_imoney_to_fmoney(uint_money)); logs_append(g_logs, "TUNET_KEEPALIVE_MONEY", smoney, NULL, 0); snprintf(smoney, sizeof(smoney), "%0.2f", tunet_imoney_to_fmoney(uint_used_money)); logs_append(g_logs, "TUNET_KEEPALIVE_USED_MONEY", smoney, NULL, 0); break; case 0xff://ff 53 65 72 76 69 63 65 20 54 65 72 6d 69 6e 61 74 65 64 21 0d 0a tunet_state = TUNET_STATE_ERROR; str = string_nappend(str, (CHAR *)(keepalive_socket_buffer->data + 1), keepalive_socket_buffer->len - 1); logs_append(g_logs, "TUNET_KEEPALIVE_ERROR", str->str, NULL, 0); str = string_free(str); keepalive_socket_buffer = buffer_clear(keepalive_socket_buffer); break; default: tunet_state = TUNET_STATE_ERROR; logs_append(g_logs, "TUNET_KEEPALIVE_RECV_UNKNOWN", NULL, NULL, 0); //dprintf("%s\n", "意外的标记"); break; } } } return OK; }
void mytunetsvc_main() { BYTE tmpbuf[1024]; BOOL bDot1xSuccess = FALSE; BOOL bDot1xFailure = FALSE; BOOL bNetworkError = FALSE; BOOL bTunetFailure = FALSE; BOOL bTunetSuccess = FALSE; BOOL bKeepAliveError = FALSE; BOOL deep_sleep; LOG *log = NULL; TICK *retry_timer = os_tick_new(10000, TRUE); TICK *state_timer = os_tick_new(1000, TRUE); INT nDot1xRetryCount = 0, nTunetRetryCount = 0; INT nRetryDelay = 5000; INT i; mytunetsvc_login(); while(!mytunetsvc_stop_flag) { /***************************************************************/ // Main loop for service. /***************************************************************/ //如果要重新登陆,则清除原来的登陆状态 deep_sleep=TRUE; if(g_Goal == GOAL_RELOGIN) { tunet_stop(); g_DelayRetry = DELAY_RETRY_NONE; nDot1xRetryCount = 0; nTunetRetryCount = 0; //userconfig = g_UserConfig; tunet_reset(); dot1x_reset(); g_Goal = GOAL_LOGIN; } if(os_tick_check(state_timer)) { g_logs = logs_append(g_logs, "MYTUNETSVC_LIMITATION", NULL, (BYTE *)&g_UserConfig.limitation, sizeof(g_UserConfig.limitation)); tmpbuf[0] = dot1x_get_state(); tmpbuf[1] = tunet_get_state(); g_logs = logs_append(g_logs, "MYTUNETSVC_STATE", NULL, tmpbuf, 2); } // 如果需要重试,则等待这个重试,而不再进行其他操作。 if(g_DelayRetry != DELAY_RETRY_NONE) { if(os_tick_check(retry_timer)) { switch(g_DelayRetry) { case DELAY_RETRY_DOT1X: if( dot1x_get_state() == DOT1X_STATE_NONE || dot1x_get_state() == DOT1X_STATE_FAILURE) { nDot1xRetryCount ++; dot1x_start(&g_UserConfig); } break; case DELAY_RETRY_TUNET: if( tunet_get_state() == TUNET_STATE_NONE || tunet_get_state() == TUNET_STATE_FAILURE || tunet_get_state() == TUNET_STATE_ERROR ) { nTunetRetryCount ++; tunet_start(&g_UserConfig); } break; } g_DelayRetry = DELAY_RETRY_NONE; } else { os_sleep(100); continue; } } if(g_Goal == GOAL_LOGIN) { //dprintf("bUseDot1x %d\n", g_UserConfig.bUseDot1x); if(g_UserConfig.bUseDot1x) { if( dot1x_get_state() == DOT1X_STATE_NONE ) { dot1x_start(&g_UserConfig); } if( dot1x_get_state() == DOT1X_STATE_SUCCESS ) { if( tunet_get_state() == TUNET_STATE_NONE ) { tunet_start(&g_UserConfig); } } else { if(dot1x_is_timeout()) { dot1x_start(&g_UserConfig); } } } else { if( tunet_get_state() == TUNET_STATE_NONE ) { tunet_start(&g_UserConfig); } } if(tunet_is_keepalive_timeout()) { tunet_reset(); if(g_UserConfig.bUseDot1x) dot1x_start(&g_UserConfig); else tunet_start(&g_UserConfig); } } /* else if(g_Goal == GOAL_LOGOUT) { tunet_stop(); g_Goal = GOAL_NONE; } */ RefetchLog: log = logs_fetch(g_logs, 0); if(log!=NULL) { if(mytunetsvc_transmit_log) mytunetsvc_transmit_log(log); #define TagIs(s) (strcmp(log->tag, s) == 0) #define StrIs(s) (strcmp(log->str, s) == 0) bDot1xSuccess = FALSE; bDot1xFailure = FALSE; bNetworkError = FALSE; bTunetFailure = FALSE; bTunetSuccess = FALSE; bKeepAliveError = FALSE; if (TagIs("DOT1X_RECV_PACK" )) { if (StrIs("EAP_SUCCESS" )) bDot1xSuccess = TRUE; if (StrIs("EAP_FAILURE" )) bDot1xFailure = TRUE; } if (TagIs("TUNET_NETWORK_ERROR" )) bNetworkError = TRUE; if (TagIs("TUNET_LOGON_ERROR" )) bTunetFailure = TRUE; if (TagIs("TUNET_LOGON_KEEPALIVE_SERVER" )) bTunetSuccess = TRUE; //if (TagIs("TUNET_KEEPALIVE_MONEY" )) AccountMoney = str //if (TagIs("TUNET_LOGON_MONEY" )) AccountMoney = str if (TagIs("TUNET_KEEPALIVE_ERROR" )) bKeepAliveError = TRUE; #undef TagIs #undef StrIs if(bDot1xSuccess) { nDot1xRetryCount = 0; } if(bTunetSuccess) { nTunetRetryCount = 0; } if(bDot1xFailure && g_UserConfig.bUseDot1x) { dot1x_reset(); g_DelayRetry = DELAY_RETRY_DOT1X; nRetryDelay = 5 + nDot1xRetryCount * 2; if(nRetryDelay >= 30) nRetryDelay = 30; nRetryDelay *= 1000; os_tick_set_delay(retry_timer, nRetryDelay); os_tick_clear(retry_timer); } if(bTunetFailure) { dot1x_reset(); g_DelayRetry = DELAY_RETRY_TUNET; nRetryDelay = 120 + nTunetRetryCount * 60; if(nRetryDelay >= 5 * 60) nRetryDelay = 5 * 60; nRetryDelay *= 1000; os_tick_set_delay(retry_timer, nRetryDelay); os_tick_clear(retry_timer); if(nTunetRetryCount >= 10) { tunet_reset(); g_Goal = GOAL_NONE; } } if( (bNetworkError || bKeepAliveError) && g_Goal == GOAL_LOGIN) { tunet_reset(); dot1x_reset(); if(g_UserConfig.bUseDot1x) { //网络错误要重新连接 802.1x nDot1xRetryCount = 0; g_DelayRetry = DELAY_RETRY_DOT1X; nRetryDelay = 5; } else { //网络错误要重新连接 Tunet //网络错误并不增加tunet的重试次数 nTunetRetryCount = 0; g_DelayRetry = DELAY_RETRY_TUNET; nRetryDelay = 1; } nRetryDelay *= 1000; os_tick_set_delay(retry_timer, nRetryDelay); os_tick_clear(retry_timer); } log = log_free(log); goto RefetchLog; } if (tunet_get_state()!=TUNET_STATE_KEEPALIVE) { deep_sleep=FALSE; } if (deep_sleep) { for (i=0; i<20; i++) { if (mytunetsvc_stop_flag) { break; } os_sleep(100); } }else { os_sleep(20); } } // printf("Loop out.\n"); tunet_stop(); //printf("tunet stopped.\n"); if(g_UserConfig.bUseDot1x) dot1x_stop(); tmpbuf[0] = DOT1X_STATE_NONE; tmpbuf[1] = DOT1X_STATE_NONE; g_logs = logs_append(g_logs, "MYTUNETSVC_STATE", NULL, tmpbuf, 2); while(1) { log = logs_fetch(g_logs, 0); if(log!=NULL) { if(mytunetsvc_transmit_log) mytunetsvc_transmit_log(log); log = log_free(log); } else { break; } } retry_timer = os_tick_free(retry_timer); state_timer = os_tick_free(state_timer); }
static int tunet_logout_recv_logout() { BYTE tmpbuf[1024 * 8]; CHAR tmp[1024]; BYTE btag; UINT32 unknowntag; BYTE *p; int len; DWORD datalen; const CHAR *LOGOUT_TUNET = "LOGOUT TUNET"; STRING *str = NULL; BOOL sr, sw, se; if(!logout_socket) return OK; os_socket_tcp_status(logout_socket, &sr, &sw, &se); if(tunet_state != TUNET_STATE_LOGOUT_RECV_LOGOUT) return OK; if(se) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_LOGOUT", NULL, 0); return ERR; } if(!sr) return OK; len = os_socket_tcp_recv(logout_socket, tmpbuf, sizeof(tmpbuf)); if(len == -1) { logs_append(g_logs, "TUNET_NETWORK_ERROR", "RECV_LOGOUT", NULL, 0); return ERR; } if(len > 0) { logout_socket_buffer = buffer_append(logout_socket_buffer, tmpbuf, len); buf2output(tmpbuf, len, tmp, len); //dprintf("data received(logout):\n%s\n", tmp); logs_append(g_logs, "TUNET_LOGOUT_RECV", NULL, tmpbuf, len); p = logout_socket_buffer->data; while(buffer_fetch_BYTE(logout_socket_buffer, &p, &btag)) { // printf("recv logout. 0x%x\n",btag); switch(btag) { case 0x10: if(!buffer_has_data(logout_socket_buffer, p, strlen(LOGOUT_TUNET) + 4)) return OK; buffer_fetch_STRING(logout_socket_buffer, &p, &str, strlen(LOGOUT_TUNET)); if(strcmp(str->str, LOGOUT_TUNET) != 0) { //dprintf("[tunet_logout_recv] unknown string\n"); tunet_state = TUNET_STATE_ERROR; return OK; } str = string_free(str); buffer_fetch_DWORD(logout_socket_buffer, &p, &unknowntag); //say "we will logout" os_socket_tcp_send(logout_socket, (BYTE *)"\x0cLOGOUT", 7); logout_socket_buffer = buffer_rollto(logout_socket_buffer, p); p = logout_socket_buffer->data; break; // case 0x0d: case 0x0e: if(!buffer_fetch_DWORD(logout_socket_buffer, &p, &datalen)) return OK; datalen = htonl(datalen); //dprintf("注销反馈消息长 %d\n", datalen); if(!buffer_fetch_STRING(logout_socket_buffer, &p, &str, datalen)) return OK; //dprintf("%s\n", str->str); logs_append(g_logs, "TUNET_LOGOUT_MSG", str->str, NULL, 0); logs_append(g_logs, "TUNET_LOGOUT", NULL, NULL, 0); str = string_free(str); tunet_state = TUNET_STATE_NONE; logout_socket_buffer = buffer_rollto(logout_socket_buffer, p); p = logout_socket_buffer->data; break; } } } return OK; }