📄 wapproxy.c
字号:
error(0, "updc_create: could not resolve interface <%s>", interface_name); close(udpc->fd); gw_free(udpc); return NULL; } fl = fcntl(udpc->fd, F_GETFL); fcntl(udpc->fd, F_SETFL, fl | O_NONBLOCK); os = udp_get_ip(udpc->addr); debug("wap.proxy",0, "bound to UDP <%s:%d>", octstr_get_cstr(os), udp_get_port(udpc->addr)); octstr_destroy(os); udpc->outgoing_list = list_create(); return udpc;} static void udpc_destroy(Udpc *udpc){ if (udpc == NULL) return; if (udpc->fd >= 0) close(udpc->fd); octstr_destroy(udpc->addr); gw_assert(list_len(udpc->outgoing_list) == 0); list_destroy(udpc->outgoing_list, NULL); gw_free(udpc);} static int add_service(int port, char *interface_name, Octstr *map_addr){ Udpc *udpc; if ((udpc = udpc_create(port, interface_name, map_addr)) == NULL) goto error; list_add_producer(udpc->outgoing_list); udpc->receiver = gwthread_create(udp_receiver, udpc); if (udpc->receiver == -1) goto error; if (gwthread_create(udp_sender, udpc) == -1) goto error; list_append(udpc_list, udpc); return 0; error: error(0, "Failed to start UDP receiver/sender thread"); udpc_destroy(udpc); return -1;} /*------------------------------------------------------------- * main calling functions * */static int udp_start(Cfg *cfg){ if (udp_running) return -1; debug("wap.proxy", 0, "starting UDP sender/receiver module"); udpc_list = list_create(); /* have a list of running systems */ add_service(CONNECTION_ORIENTED_PORT, octstr_get_cstr(interface_name), NULL); /* wsp/wtp */ list_add_producer(incoming_wdp); udp_running = 1; return 0;}static Udpc *udpc_find_mapping(Msg *msg, int inbound){ int i; Udpc *udpc; Octstr *addr; /* check if there is allready a bound UDP port */ list_lock(udpc_list); for (i=0; i < list_len(udpc_list); i++) { udpc = list_get(udpc_list, i); /* decide if we compare against inbound or outbound traffic mapping */ addr = inbound ? udpc->map_addr : udpc->addr; if (msg->wdp_datagram.source_port == udp_get_port(addr) && octstr_compare(msg->wdp_datagram.source_address, udp_get_ip(addr)) == 0) { list_unlock(udpc_list); return udpc; } } list_unlock(udpc_list); return NULL;}/* * this function receives an WDP message and adds it to * corresponding outgoing_list. */static int udp_addwdp_from_server(Msg *msg){ Udpc *udpc; Octstr *os; Octstr *source; if (!udp_running) return -1; assert(msg != NULL); assert(msg_type(msg) == wdp_datagram); octstr_destroy(msg->wdp_datagram.source_address); msg->wdp_datagram.source_address = octstr_create(octstr_get_cstr(msg->wdp_datagram.destination_address)); msg->wdp_datagram.source_port = msg->wdp_datagram.destination_port; if ((udpc = udpc_find_mapping(msg, 0)) == NULL) /* there should have been one */ panic(0,"Could not find UDP mapping, internal error"); /* insert the found mapped destination */ octstr_destroy(msg->wdp_datagram.source_address); octstr_destroy(msg->wdp_datagram.destination_address); msg->wdp_datagram.destination_address = udp_get_ip(udpc->map_addr); msg->wdp_datagram.destination_port = udp_get_port(udpc->map_addr); /* now search for our inbound UDP socket */ os = octstr_duplicate(interface_name); source = udp_create_address(os, CONNECTION_ORIENTED_PORT); msg->wdp_datagram.source_address = udp_get_ip(source); msg->wdp_datagram.source_port = udp_get_port(source); if ((udpc = udpc_find_mapping(msg, 0)) == NULL) panic(0,"Could not find main inbound UDP socket, internal error"); /* * ok, got the destination, got the socket, * now put it on the outbound queue */ list_produce(udpc->outgoing_list, msg); octstr_destroy(os); return 0;}/* * this function receives an WDP message and checks if a UDP * service for this client has to be created */static int udp_addwdp_from_client(Msg *msg){ Udpc *udpc; Octstr *map_addr; Octstr *os; Octstr *source; if (!udp_running) return -1; assert(msg != NULL); assert(msg_type(msg) == wdp_datagram); /* * Check if there is allready a bound UDP port for this mapping. * If not create a mapping and bind the mapped UDP port * The mapped port is simply 2x of the client port. */ if ((udpc = udpc_find_mapping(msg, 1)) == NULL) { info(0, "Creating UDP mapping <%s:%ld> <-> <%s:%ld>", octstr_get_cstr(msg->wdp_datagram.source_address), msg->wdp_datagram.source_port, octstr_get_cstr(msg->wdp_datagram.destination_address), msg->wdp_datagram.source_port*2); map_addr = udp_create_address(msg->wdp_datagram.source_address, msg->wdp_datagram.source_port); add_service(msg->wdp_datagram.source_port * 2, octstr_get_cstr(interface_name), map_addr); /* now we should find it in the udpc_list */ if ((udpc = udpc_find_mapping(msg, 1)) == NULL) panic(0,"Could not find UDP mapping, internal error"); } /* now swap the message addressing */ octstr_destroy(msg->wdp_datagram.source_address); octstr_destroy(msg->wdp_datagram.destination_address); os = octstr_duplicate(interface_name); source = udp_create_address(os, msg->wdp_datagram.source_port * 2); msg->wdp_datagram.source_address = udp_get_ip(source); msg->wdp_datagram.source_port = udp_get_port(source); msg->wdp_datagram.destination_address = octstr_duplicate(wapgw); msg->wdp_datagram.destination_port = CONNECTION_ORIENTED_PORT; octstr_destroy(os); list_produce(udpc->outgoing_list, msg); return -1;}static int udp_shutdown(void){ if (!udp_running) return -1; debug("bb.thread", 0, "udp_shutdown: Starting avalanche"); list_remove_producer(incoming_wdp); return 0;}static int udp_die(void){ Udpc *udpc; if (!udp_running) return -1; /* * remove producers from all outgoing lists. */ debug("bb.udp", 0, "udp_die: removing producers from udp-lists"); while ((udpc = list_consume(udpc_list)) != NULL) { list_remove_producer(udpc->outgoing_list); } list_destroy(udpc_list, NULL); udp_running = 0; return 0;}/*------------------------------------------------------------- * main consumer threads * */static void wdp_router(void *arg){ Msg *msg; list_add_producer(flow_threads); while (1) { if ((msg = list_consume(outgoing_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); udp_addwdp_from_server(msg); } udp_die(); list_remove_producer(flow_threads);}static void service_router(void *arg){ Msg *msg; list_add_producer(flow_threads); while (1) { if ((msg = list_consume(incoming_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); udp_addwdp_from_client(msg); } udp_die(); list_remove_producer(flow_threads);}/*------------------------------------------------------------- * main functions * */static void help(void) { info(0, "Usage: wapproxy [options] host ..."); info(0, "where host is the real wap gw to forward to and options are:"); info(0, "-v number"); info(0, " set log level for stderr logging"); info(0, "-i interface"); info(0, " bind to the given interface for UDP sockets"); info(0, "-m"); info(0, " dump WDP/UDP packets, msg_dump()"); info(0, "-e"); info(0, " dump WAP event packets, wap_event_dump()"); info(0, "-t"); info(0, " dump WTP PDUs, wtp_pdu_dump()");}int main(int argc, char **argv) { int opt; Cfg *cfg = NULL; gwlib_init(); while ((opt = getopt(argc, argv, "v:meti:")) != EOF) { switch (opt) { case 'v': log_set_output_level(atoi(optarg)); break; case 'm': verbose += 1; break; case 'e': verbose += 2; break; case 't': verbose += 4; break; case 'h': help(); exit(0); case 'i': interface_name = octstr_create(optarg); break; case '?': default: error(0, "Invalid option %c", opt); help(); panic(0, "Stopping."); } } if (optind == argc) { help(); exit(0); } /* get the host or IP of the real wap gw to forward the WDP packets */ wapgw = octstr_create(argv[optind]); /* if no interface was given use 0.0.0.0 */ if (!interface_name) interface_name = octstr_create("*"); report_versions("wapproxy"); /* initialize main inbound and outbound queues */ outgoing_wdp = list_create(); incoming_wdp = list_create(); flow_threads = list_create(); outgoing_wdp_counter = counter_create(); incoming_wdp_counter = counter_create(); /* start the main UDP listening threads */ udp_start(cfg); list_add_producer(outgoing_wdp); debug("bb", 0, "starting WDP routers"); if (gwthread_create(service_router, NULL) == -1) panic(0, "Failed to start a new thread for inbound WDP routing"); if (gwthread_create(wdp_router, NULL) == -1) panic(0, "Failed to start a new thread for outbound WDP routing"); gwthread_sleep(5.0); /* give time to threads to register themselves */ while (list_consume(flow_threads) != NULL) ; udp_shutdown(); list_remove_producer(outgoing_wdp); list_destroy(flow_threads, NULL); list_destroy(incoming_wdp, NULL); list_destroy(outgoing_wdp, NULL); counter_destroy(incoming_wdp_counter); counter_destroy(outgoing_wdp_counter); octstr_destroy(interface_name); octstr_destroy(wapgw); gwlib_shutdown(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -