📄 drive_wapbox.c
字号:
}static Msg *wdp_create(Octstr *data, Client *client) { Msg *msg; msg = msg_create(wdp_datagram); msg->wdp_datagram.source_address = octstr_create("127.0.0.1"); msg->wdp_datagram.source_port = client->port; msg->wdp_datagram.destination_address = octstr_create("127.0.0.1"); msg->wdp_datagram.destination_port = 9201; msg->wdp_datagram.user_data = octstr_duplicate(data); return msg;}static void send_pdu(Octstr *pdu, Connection *boxc, Client *client) { Msg *msg; Octstr *data; if (verbose_debug) { debug("test", 0, "Sending:"); octstr_dump(pdu, 0); } msg = wdp_create(pdu, client); data = msg_pack(msg); conn_write_withlen(boxc, data); octstr_destroy(data); msg_destroy(msg);}static void send_invoke_connect(Connection *boxc, Client *client) { Octstr *pdu; gw_assert(client != NULL); gw_assert(client->wtp_invoked == 0); gw_assert(client->wsp_connected == 0); pdu = wtp_invoke_create(2); set_tid(pdu, client->wtp_tid); add_wsp_connect(pdu); send_pdu(pdu, boxc, client); octstr_destroy(pdu); client->wtp_invoked = 1;}static void send_invoke_get(Connection *boxc, Client *client) { Octstr *pdu; gw_assert(client != NULL); gw_assert(client->wtp_invoked == 0); gw_assert(client->wsp_connected == 1); pdu = wtp_invoke_create(2); set_tid(pdu, client->wtp_tid); add_wsp_get(pdu); send_pdu(pdu, boxc, client); octstr_destroy(pdu); client->wtp_invoked = 1;}static void record_disconnect(Client *client) { client->wsp_connected = 0; client->wsp_session_id = -1; client->pages_fetched = 0; increment_tid(client);}static void send_invoke_disconnect(Connection *boxc, Client *client) { Octstr *pdu; gw_assert(client != NULL); gw_assert(client->wtp_invoked == 0); gw_assert(client->wsp_connected == 1); /* Kannel can't handle it as class 1 yet, so send class 0 */ pdu = wtp_invoke_create(0); set_tid(pdu, client->wtp_tid); add_wsp_disconnect(pdu, client->wsp_session_id); send_pdu(pdu, boxc, client); octstr_destroy(pdu); record_disconnect(client); client_done(client);}static void handle_connect_reply(Connection *boxc, Client *client, Octstr *pdu) { Octstr *ack; gw_assert(client); gw_assert(client->wtp_invoked); gw_assert(!client->wsp_connected); if (octstr_get_char(pdu, 3) != ConnectReply_PDU) { error(0, "Unexpected CONNECT reply"); octstr_dump(pdu, 0); return; } ack = wtp_ack_create(); set_tid(ack, client->wtp_tid); send_pdu(ack, boxc, client); octstr_destroy(ack); client->wtp_invoked = 0; increment_tid(client); client->wsp_connected = 1; client->wsp_session_id = get_varint(pdu, 4); send_invoke_get(boxc, client);}static void handle_get_reply(Connection *boxc, Client *client, Octstr *pdu) { Octstr *ack; gw_assert(client); gw_assert(client->wtp_invoked); gw_assert(client->wsp_connected); if (octstr_get_char(pdu, 3) != Reply_PDU) { error(0, "Unexpected GET reply"); octstr_dump(pdu, 0); return; } ack = wtp_ack_create(); set_tid(ack, client->wtp_tid); send_pdu(ack, boxc, client); octstr_destroy(ack); client->wtp_invoked = 0; increment_tid(client); client->pages_fetched++; if (client->pages_fetched == req_per_session) { send_invoke_disconnect(boxc, client); } else { client_done(client); }}static void handle_reply(Connection *boxc, Msg *reply) { Client *client; Octstr *wtp; int type; int dumped = 0; gw_assert(reply != NULL); gw_assert(reply->type == wdp_datagram); client = find_client(reply->wdp_datagram.destination_port); if (client == NULL) panic(0, "got packet for nonexisting client %ld", (long) reply->wdp_datagram.destination_port); wtp = reply->wdp_datagram.user_data; type = wtp_type(wtp); if (verbose_debug) { debug("test", 0, "Received:"); octstr_dump(wtp, 0); dumped = 1; } if (client->wtp_invoked == 0) { error(0, "Got packet for client that wasn't waiting"); if (!dumped) { octstr_dump(wtp, 0); dumped = 1; } return; } /* Server should invert the MSB of the tid in its replies */ if (get_tid(wtp) != (client->wtp_tid ^ 0x8000)) { error(0, "Got packet with wrong tid %d, expected %d.", get_tid(wtp), client->wtp_tid ^ 0x8000); if (!dumped) { octstr_dump(wtp, 0); dumped = 1; } return; } /* We're going to be stupid here, and assume that replies that * look vaguely like what we expect are actually what we wanted. */ if (client->wsp_connected == 0 && type == RESULT) { handle_connect_reply(boxc, client, wtp); } else if (client->wsp_connected == 1 && type == RESULT) { handle_get_reply(boxc, client, wtp); } else if (client->wsp_connected == 2 && type == ACK) { record_disconnect(client); client_done(client); } else { error(0, "Got unexpected packet"); if (!dumped) { octstr_dump(wtp, 0); dumped = 1; } }}static void start_request(Connection *boxc, Client *client) { gw_assert(client != NULL); gw_assert(client->wsp_connected != 2); gw_assert(client->wtp_invoked == 0); if (client->wsp_connected == 0) { send_invoke_connect(boxc, client); } else { send_invoke_get(boxc, client); }}static long run_requests(Connection *boxc) { int requests_sent; Octstr *data; Msg *msg; int ret; requests_sent = 0; requests_complete = 0; while (requests_complete < max_requests) { data = conn_read_withlen(boxc); if (!data) { Client *client; if (requests_sent < max_requests && (client = list_extract_first(ready_clients))) { start_request(boxc, client); requests_sent++; } ret = conn_wait(boxc, TIMEOUT); if (ret < 0 || conn_eof(boxc)) panic(0, "Wapbox dead."); if (ret == 1) break; /* Timed out. */ } else { msg = msg_unpack(data); if (!msg) { octstr_dump(data, 0); panic(0, "Received bad data from wapbox."); } if (msg->type == wdp_datagram) handle_reply(boxc, msg); msg_destroy(msg); } octstr_destroy(data); } if (requests_complete < max_requests) info(0, "Timeout. %ld requests unsatisfied.", max_requests - requests_complete); return requests_complete;}static void help(void) { info(0, "Usage: drive_wapbox [options...]\n"); info(0, " -r requests Stop after this many; default 1."); info(0, " -c clients # of concurrent clients; default 1."); info(0, " -w wapport Port wapbox should connect to; default 30188"); info(0, " -u url Use this url instead of internal http server"); info(0, " -g requests Number of requests per WSP session; default 1"); info(0, " -U Set the User ack flag on all WTP transactions");}int main(int argc, char **argv) { int opt; struct timeval start, end; Connection *boxc; long completed; double run_time; gwlib_init(); while ((opt = getopt(argc, argv, "hv:r:c:w:du:Ug:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'r': max_requests = atol(optarg); break; case 'c': max_clients = atol(optarg); break; case 'w': wapbox_port = atoi(optarg); break; case 'u': http_url = octstr_create(optarg); break; case 'U': user_ack = 1; break; case 'h': help(); exit(0); case 'd': verbose_debug = 1; break; case 'g': req_per_session = atoi(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (!http_url) http_port = start_http_thread(); boxc = start_wapbox(); initialize_clients(); if (gettimeofday(&start, NULL) < 0) panic(errno, "gettimeofday failed"); completed = run_requests(boxc); if (gettimeofday(&end, NULL) < 0) panic(errno, "gettimeofday failed"); conn_destroy(boxc); run_time = end.tv_sec - start.tv_sec; run_time += (double) (end.tv_usec - start.tv_usec) / 1000000.0; /* We must have timed out. Don't count the waiting time. */ if (completed < max_requests) run_time -= TIMEOUT; info(0, "%ld request%s in %0.1f seconds, %0.1f requests/s.", completed, completed != 1 ? "s" : "", run_time, max_requests / run_time); dying = 1; http_close_all_ports(); if (!http_url) gwthread_join(http_thread_id); destroy_clients(); octstr_destroy(http_url); gwlib_shutdown(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -