/*ケース:切断*/ inline void case_action_dis_connect(CONNECTION_DATA* con){ REQUEST* req = &con->request; FILE* log_file; int code; USER_INFO* info = req->info; //ログオフ if((code = logoff_user(info,req->pass,req->session_id,con->ip)) != USER_LOGOFF_SUCCESS){ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Logoff Error:%d\n",info->name,code); unlock_log_file(); //KICKED connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return; } //成功 log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Logoff Success\n",info->name); unlock_log_file(); connection_return_req_data_header(con,CONNECTION_ACTION_DISCONNECT); initCrypt(&info->crypt);//この時点で暗号処理の初期化。 }
void log_response( int status, long long log_file_id ) { FILE *lfp = NULL; struct timeval Tps; struct timezone Tpf; long long t_after_sec = 0, t_after_usec = 0, t_after = 0; char *logfile = getenv("Q_LOGFILE"); if ( logfile != NULL ) { gettimeofday (&Tps, &Tpf); t_after_sec = (long long)Tps.tv_sec; t_after_usec = (long long)Tps.tv_usec; t_after = t_after_sec * 1000000 + t_after_usec; status = lock_log_file(); lfp = fopen(logfile, "a"); if ( lfp != NULL ) { fprintf(lfp, "%lld,%d,%lld\n", log_file_id, status, t_after); } fclose_if_non_null(lfp); status = unlock_log_file(); } }
/*接続*/ void connection_connect(CONNECTION_DATA* con){ /*変数宣言*/ TCPsocket *sock = &con->socket; char* str; int content_length = -1; int is_err = false; FILE* log_file; /*接続先IPを取得*/ con->ip = SDLNet_TCP_GetPeerAddress(*sock); /*ビジー状態に設定*/ if(!lock_connection(con)){ SDLNet_TCP_Close(*sock); return; } /*ヘッダを判断する*/ str = NetUtl_readLine(sock); if(str == null){ /*通信終わり*/ SDLNet_TCP_Close(*sock); /*接続終了フラグ*/ unlock_connection(con); return; } if(strncmp(str,POST_HEADER,strlen(POST_HEADER)) != 0){ is_err = true; } /*とりあえず最後まで受信する。*/ if(is_err){//エラー /*ログに追加*/ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"%s\n",str); unlock_log_file(); //最後まで受信するだけ while(*(str = NetUtl_readLine(sock)) != END_CHAR){ } }else{//ヘッダを取得する while(*(str = NetUtl_readLine(sock)) != END_CHAR){ if(content_length < 0){ if(strncmp( str, CONTENT_LENGTH_HEADER, strlen(CONTENT_LENGTH_HEADER) ) == 0){ sscanf(str,CONTENT_LENGTH_HEADER_F,&content_length); } }//else if(){} } } if(!is_err && content_length >= 0){/*とりあえず通信するに値する*/ connection_do_request(con,content_length); }else{/*まったく関係ない*/ connection_send_error(sock); } /*通信終わり*/ SDLNet_TCP_Close(*sock); /*接続終了フラグ*/ unlock_connection(con); }
/*ケース:接続*/ inline void case_action_connect(CONNECTION_DATA* con){ REQUEST* req = &con->request; FILE* log_file; int code; USER_INFO* info = req->info; //ログイン code = login_user(info,req->pass,req->session_id,con->ip); if(code == USER_LOGOFF_SUCCESS){//時間切れでログオフ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Error:Time out and Loggoff\n",info->name); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_DISCONNECT); initCrypt(&info->crypt);//この時点で暗号処理の初期化。 return; }else if(code != USER_LOGIN_SUCCESS){//それ以外でエラー log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Error:%d\n",info->name,code); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return; } //成功 log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Login Success\n",info->name); unlock_log_file(); connection_return_req_data_header(con,CONNECTION_ACTION_ACCEPT); //次のストリームへ nextStream(&info->crypt); }
void log_request( int argc, char **argv, long long *ptr_log_file_id ) { int status = 0; FILE *lfp = NULL; struct timeval Tps; struct timezone Tpf; long long t_before_sec = 0, t_before_usec = 0, t_before = 0; char *logfile = getenv("Q_LOGFILE"); if ( logfile != NULL ) { gettimeofday(&Tps, &Tpf); t_before_sec = (long long)Tps.tv_sec; t_before_usec = (long long)Tps.tv_usec; t_before = t_before_sec * 1000000 + t_before_usec; *ptr_log_file_id = (t_before << 16) + getpid(); status = lock_log_file(); lfp = fopen(logfile, "a"); if ( lfp != NULL ) { fprintf(lfp, "%lld,%d,%lld,", *ptr_log_file_id, argc, t_before_sec); for ( int j = 0; j < argc; j++ ) { if ( j > 0 ) { fprintf(lfp, ","); } fprintf(lfp, "\""); for ( char *cptr = argv[j]; *cptr != '\0'; cptr++ ) { if ( ( *cptr == '"' ) || ( *cptr == '\\' ) ) { fprintf(lfp, "\\"); } fprintf(lfp, "%c", *cptr); } fprintf(lfp, "\""); } for ( int i = argc; i < MAX_NUM_ARGS; i++ ) { fprintf(lfp, ",\"\""); } } fclose_if_non_null(lfp); status = unlock_log_file(); } }
/*ケース:HTTPリクエストの処理*/ inline void case_action_request(CONNECTION_DATA* con){ REQUEST* req = &con->request; FILE* log_file; int code; USER_INFO* info = req->info; //チェック code = check_user(info,req->pass,req->session_id,con->ip); if(code == USER_LOGOFF_SUCCESS){//時間切れでログオフ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Request Error:Time out and Loggoff\n",info->name); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_DISCONNECT); initCrypt(&info->crypt);//この時点で暗号処理の初期化。 return; }else if(code != USER_CHECK_SUCCESS){//それ以外のエラー log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Request Error:%d\n",info->name,code); unlock_log_file(); //KICK connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return; } //送信 if(connect_request(req) && send_request(req)){ TCPsocket* s_sock = request_get_sock(req); char data[4096]; int total_size = 0; int size; //ヘッダを返す connection_return_req_data_header(con,CONNECTION_ACTION_RESULT); //データ while((size = SDLNet_TCP_Recv(*s_sock,data,4096)) > 0){ total_size+=size; if(connection_return_req_data(con,data,size) < size){ {//接続リセット char* request_str = connection_get_req_url(req->data,req->data_size); log_file = lock_log_file(); time_output(); fprintf(log_file,"(%s)<%s:%d>%s Connection reset.\n",info->name,req->host,req->host_port,request_str); unlock_log_file(); free(request_str); } //次のストリームへ nextStream(&info->crypt); request_close_connection(req); return; } } {//データ送信終了 char* request_str = connection_get_req_url(req->data,req->data_size); log_file = lock_log_file(); time_output(); fprintf(log_file,"(%s)<%s:%d>%s %dbytes\n",info->name,req->host,req->host_port,request_str,total_size); unlock_log_file(); free(request_str); } }else{//エラー { char* request_str = connection_get_req_url(req->data,req->data_size); log_file = lock_log_file(); time_output(); fprintf(log_file,"(%s)<%s:%d>%s ConnectionError\n",info->name,req->host,req->host_port,request_str); unlock_log_file(); free(request_str); } connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); } //次のストリームへ nextStream(&info->crypt); request_close_connection(req); }
/*リクエストを処理するに値する*/ int connection_do_request(CONNECTION_DATA* con,int content_length){ FILE* log_file; TCPsocket* c_sock = &con->socket; char* recv; int idx = 0; int size; int total_size = 0; USER_INFO* info; CRYPT* crypt; //リクエスト関係 Uint32 user_id; Uint32 action_code; //非暗号化データ user_id = NetUtl_recvInt(c_sock); idx+=4; action_code = NetUtl_recvInt(c_sock); idx+=4; content_length -= idx; idx = 0; //この時点でユーザ検索 info = get_user(user_id); if(info == null){//ユーザが見つからない char ch; int size = 0; log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"User NOT FOUND ID:%08x\n",user_id); unlock_log_file(); //最後まで受信しないと、エラーになりがち。 while(size < content_length && SDLNet_TCP_Recv(*c_sock, &ch, 1) == 1){ size++; } return false; } //接続 if(!connect_user(info)){ char ch; int size = 0; //ログ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Already connected.\n",info->name); unlock_log_file(); //最後まで受信しないと、エラーになりがち。 while(size < content_length && SDLNet_TCP_Recv(*c_sock, &ch, 1) == 1){ size++; } return false; } //鍵を使うと宣言 crypt = &info->crypt; startCrypt(crypt); //暗号化データ受信 recv = malloc(content_length); while((size = recvCrypt(crypt,c_sock, &recv[total_size],content_length-total_size)) > 0){ total_size += size; if(total_size >= content_length){ break; } } //サイズがあわない。 if(total_size < content_length){ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Invalid Size Request.\n",info->name); unlock_log_file(); //処理 free(recv); disconnect_user(info); //KICKED connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return false; } //リクエスト完成 if(!init_request(&con->request,info,action_code,recv,total_size)){ log_file = lock_log_file(); time_output(); ip_output(con->ip); fprintf(log_file,"(%s)Invalid Request.\n",info->name); unlock_log_file(); //処理 free_request(&con->request); disconnect_user(info); //KICKED connection_return_req_data_header(con,CONNECTION_ACTION_KICKED); return false; } //スイッチ switch_request(con); disconnect_user(info); free_request(&con->request); return true; }