📄 fakewap.c
字号:
int timeout ){ int ret; unsigned char msg[1024*64]; int msg_len = 0; int fResponderIsDead = 1; /* assume this by default */ Octstr *datagram, *dummy; /* ** Loop until we get the expected response or do timeout */ for (;;) { if (timeout != 0) { ret = read_available(fd, timeout * 1000 * 1000); if (ret <= 0) { info(0, "Timeout while receiving from socket.\n"); if(nofailexit){ continue; }else{ return fResponderIsDead ? -1 : 0; } /* continue if we got ack? */ } } ret = udp_recvfrom(fd, &datagram, &dummy); if (ret == 0) { octstr_get_many_chars(msg, datagram, 0, octstr_len(datagram)); msg_len = octstr_len(datagram); } octstr_destroy(datagram); octstr_destroy(dummy); if (ret == -1) { error(0, "recv() from socket failed"); return -1; } if (hdr != NULL) { /* ** Ignore extra header bits, WAP GWs return different values */ if (msg_len >= hdr_len && GET_WTP_PDU_TYPE(msg) == GET_WTP_PDU_TYPE(hdr) && (hdr_len <= 3 || !memcmp( msg+3, hdr+3, hdr_len-3 ))) { break; } /* ** Handle TID test, the answer is: Yes, we have an outstanding ** transaction with this tid. We must turn on TID_OK-flag, too. ** We have a separate tid verification PDU. */ else if (GET_WTP_PDU_TYPE(msg) == WTP_PDU_ACK && GET_TID(msg) == tid) { print_msg( "Received tid verification", msg, msg_len ); wap_msg_send( fd, WTP_TidVe, sizeof(WTP_TidVe), tid, 0, NULL, 0 ); } else if (GET_WTP_PDU_TYPE(msg) == WTP_PDU_ABORT) { print_msg( "Received WTP Abort", msg, msg_len ); } else if (GET_WTP_PDU_TYPE(msg) == WTP_PDU_RESULT) { break; } else { print_msg( "Received unexpected message", msg, msg_len ); } fResponderIsDead = 0; } else { hdr_len = 0; break; } } print_msg( "Received packet", msg, msg_len ); print_data( "Received data", msg, msg_len ); if (data != NULL && msg_len > hdr_len) { data_len = min( data_len, msg_len - hdr_len ); memcpy( data, msg+hdr_len, data_len); } else data_len = 0; return data_len;}static int get_next_transaction(void) { int i_this; mutex_lock( mutex ); i_this = num_sent + 1; if (max_send == MAX_SEND || num_sent < max_send) num_sent++; mutex_unlock( mutex ); return i_this;}/*** Function (or thread) sets up a dgram socket. Then it loops: WTL/WSP** Connect, Get a url and Disconnect until all requests are have been done.*/static void client_session( void * arg){ int fd; int ret; int url_len = 0, url_off = 0; double nowsec, lastsec, tmp, sleepTime; long uSleepTime; struct timeval now; struct timezone tz; char * url; unsigned char sid[20]; int sid_len = 0; unsigned char buf[64*1024]; unsigned char reply_hdr[32]; long timeout = 10; /* wap gw is broken if no input */ unsigned short tid = 0; unsigned short old_tid; int tid_new = 0; int connection_retries = 0; int i_this; fd = udp_client_socket(); if (fd == -1) panic(0, "Couldn't create socket."); /* ** Loop until all URLs have been requested */ for (;;) { /* ** Get start time of this request */ gettimeofday(&now, &tz); lastsec = (double) now.tv_sec + now.tv_usec / 1e6; /* ** Get next transaction number or exit if too many transactions */ i_this = get_next_transaction(); if (max_send != MAX_SEND && i_this > max_send) break; /* ** Connect, save sid from reply and finally ack the reply */ old_tid = tid; tid = next_tid(old_tid); tid_new = (tid < old_tid); /* Did we wrap? */ ret = wap_msg_send( fd, WSP_Connect, sizeof(WSP_Connect), tid, tid_new, NULL, 0 ); if (ret == -1) panic(0, "Send WSP_Connect failed"); CONSTRUCT_EXPECTED_REPLY_HDR( reply_hdr, WSP_ConnectReply, tid ); ret = wap_msg_recv( fd, reply_hdr, sizeof(WSP_ConnectReply), tid, buf, sizeof(buf), timeout ); if (ret == -1) panic(0, "Receive WSP_ConnectReply failed"); if (ret > 2) { sid_len = ReadVarIntLen(buf); memcpy( sid, buf, sid_len); } /* ** Send abort and continue if we get an unexpected reply */ if (ret == 0) { if (connection_retries++ > 3) { panic(0, "Cannot connect WAP GW!"); } wap_msg_send( fd, WTP_Abort, sizeof(WTP_Abort), tid, tid_new, NULL, 0 ); continue; } else { connection_retries = 0; } ret = wap_msg_send( fd, WTP_Ack, sizeof(WTP_Ack), tid, tid_new, NULL, 0 ); if (ret == -1) panic(0, "Send WTP_Ack failed"); /* ** Request WML page with the given URL */ old_tid = tid; tid = next_tid(old_tid); tid_new = (tid < old_tid); /* Did we wrap? */ url = choose_message(urls, num_urls); url_len = strlen(url); url_off = StoreVarInt( buf, url_len ); memcpy( buf+url_off, url, url_len ); ret = wap_msg_send( fd, WSP_Get, sizeof(WSP_Get), tid, tid_new, buf, url_len+url_off ); if (ret == -1) break; CONSTRUCT_EXPECTED_REPLY_HDR( reply_hdr, WSP_Reply, tid ); ret = wap_msg_recv( fd, reply_hdr, sizeof(WSP_Reply), tid, buf, sizeof(buf), timeout ); if (ret == -1) break; /* ** If we are testing separation, we concatenate WTP_Ack and ** WSP_Disconnect messages. */ if (test_separation){ ret = wap_msg_send(fd, WSP_Concat, sizeof(WSP_Concat), tid, tid_new, sid, sid_len); if (ret == -1) break; } else { ret = wap_msg_send( fd, WTP_Ack, sizeof(WTP_Ack), tid, tid_new, NULL, 0 ); if (ret == -1) break; /* ** Finally disconnect with the sid returned by connect reply */ ret = wap_msg_send( fd, WSP_Disconnect, sizeof(WSP_Disconnect), tid, tid_new, sid, sid_len ); if (ret == -1) break; } /* ** Get end time of the request */ gettimeofday(&now, &tz); nowsec = (double) now.tv_sec + now.tv_usec / 1e6; tmp = nowsec - lastsec; /* Duration of request */ sleepTime = interval-tmp; /* Amount of time left to sleep */ uSleepTime = sleepTime * 1e6; mutex_lock( mutex ); if (tmp < besttime) besttime = tmp; if (tmp > worsttime) worsttime = tmp; totaltime += tmp; mutex_unlock( mutex ); if (verbose == 1) { info(0, "fakewap: finished session # %d", i_this); } /* ** If we've done all the requests, then don't bother to sleep */ if (i_this >= max_send) break; if (tmp < (double)interval) { usleep( uSleepTime ); } } close(fd); /* The last end_time stays */ mutex_lock( mutex ); time(&end_time); mutex_unlock( mutex );}static void help(void) { info(0, "\n%s", usage);}/* The main program. */int main(int argc, char **argv){ int i, opt; double delta; int proto_version, pdu_type, tcl, tid_new;#ifdef SunOS struct sigaction alrm; alrm.sa_handler = SIG_IGN; sigaction(SIGALRM,&alrm,NULL);#endif gwlib_init(); proto_version = 0; pdu_type = 1; tcl = 2; tid_new = 0; hostname = octstr_create("localhost"); while ((opt = getopt(argc, argv, "Fhvc:g:p:P:m:i:t:V:T:t:nsd:w")) != EOF) { switch (opt) { case 'g': octstr_destroy(hostname); hostname = octstr_create(optarg); break; case 'p': port = atoi(optarg); break; case 'm': max_send = atoi(optarg); break; case 'i': interval = atof(optarg); break; case 'c': threads = atoi(optarg); break; case 'V': proto_version = atoi(optarg); break; case 'T': pdu_type = atoi(optarg); break; case 't': tcl = atoi(optarg); break; case 'n': tid_new = 1; break; case 's': test_separation = 1; break; case 'd': tid_addition = atoi(optarg); break; case 'v': verbose = 1; break; case 'h': help(); exit(0); break; case 'F': nofailexit=1; break; case 'w': writedata = 1; break; case '?': default: error(0, "Unknown option %c", opt); help(); panic(0, "Stopping."); } } time(&start_time); if (optind >= argc) panic(0, "%s", usage); if (verbose != 1) { log_set_output_level (GW_INFO); } WSP_Connect[3] += (proto_version&3)<<6; WSP_Connect[0] += (pdu_type&15)<<3; WSP_Connect[3] += tcl&3; WSP_Connect[3] += (tid_new&1)<<5; gateway_addr = udp_create_address(hostname, port); urls = argv + optind; num_urls = argc - optind; srand((unsigned int) time(NULL)); mutex = mutex_create(); info(0, "fakewap starting"); if (threads < 1) threads = 1; /* ** Start 'extra' client threads and finally execute the ** session of main thread */ for (i = 1; i < threads; i++) gwthread_create(client_session, NULL); client_session(NULL); /* Wait for the other sessions to complete */ gwthread_join_every(client_session); info(0, "fakewap complete."); info(0, "fakewap: %d client threads made total %d transactions.", threads, num_sent); delta = difftime(end_time, start_time); info( 0, "fakewap: total running time %.1f seconds", delta); info( 0, "fakewap: %.1f messages/seconds on average", num_sent / delta); info( 0, "fakewap: time of best, worst and average transaction: " "%.1f s, %.1f s, %.1f s", besttime, worsttime, totaltime / num_sent ); octstr_destroy(hostname); octstr_destroy(gateway_addr); mutex_destroy(mutex); gwlib_shutdown(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -